Java 언어의 영광스러운 클래스


96

표준 Java API의 일부 클래스는 다른 클래스와 약간 다르게 처리됩니다. 컴파일러 및 / 또는 JVM의 특별한 지원 없이는 구현할 수없는 클래스에 대해 이야기하고 있습니다.

내가 바로 생각해 낸 것은 다음과 같습니다.

  • Object (분명히) 다른 것들 중에서도 슈퍼 클래스가 없습니다.
  • String 언어는 + 연산자에 대한 특별한 지원을 가지고 있기 때문입니다.
  • Thread 실행을 "포크"하는 바이트 코드 명령이 없다는 사실에도 불구하고 마법의 start () 메서드가 있기 때문입니다.

나는 이것들과 같은 모든 클래스가 JLS에 언급 된 어떤 식 으로든 있다고 생각합니다. 틀 렸으면 말해줘.

어쨌든, 어떤 다른 클래스가 있습니까? Java 언어로 된 "영광 클래스"의 전체 목록이 있습니까?


2
제네릭 은 거의 적합하지만 정답 은 아닙니다. 컴파일러 트릭을 사용하여 구현되지만 하나의 클래스로 격리되지는 않습니다.
Bill the Lizard

2
그들은 모두 경외 유형입니다. ;-)
starblue

1
"thread.start"가 마법인가? 확실히이 작업을 수행하기 위해 호출 된 일부 네이티브 코드 일 뿐입니 까?
jcoder 2010-08-13

그 생각도 나에게 충격을 주었다. 아마도 JNI만으로도 Thread 클래스를 구현하기에 충분할 것입니다. 이 작업을 시도하면 OS 수준의 스레드 API를 사용하고 start () 메서드 구현에서 실행을 포크하고 포크 된 스레드에서 run () 메서드를 실행 한 다음 반환 할 것이라고 가정합니다. 하지만 OS 스레드가 계속 실행됩니다. JVM이 만든 스레드와 함께 원활하게 실행됩니까? JLS 메모리 모델 등을 존중합니까?
aioobe 2010 년

2
사양에 따르면 스레드를 생성하는 유일한 방법은 Thread 클래스 ( java.sun.com/docs/books/jvms/second_edition/html/… )를 사용하는 것입니다. 물론 JVM과의 순진한 수준의 통신에 의존하지만 자신의 JNI를 수행하면 스레드를 시작할 수 있지만 JVM이 수행중인 작업 (잠금, 메모리 모델 등)을 이해하지 못할 것입니다. ). 스레드는 스펙이 스레드를 시작하는 유일한 방법 인 특수 권한을 지정한다는 점에서 특권이 있습니다.
Yishai 2010-08-13

답변:


35

다양한 답변이 있으므로 모두 수집하고 일부를 추가하는 것이 유용 할 것이라고 생각했습니다.

클래스

  • AutoBoxing 클래스-컴파일러는 특정 클래스 만 허용합니다.
  • 클래스 -자체 리터럴 (예 : int.class)이 있습니다. 또한 새 인스턴스를 생성하지 않고 일반 유형을 추가합니다.
  • 문자열 -오버로드 된 + 연산자 및 리터럴 지원
  • Enum -switch 문에서 사용할 수있는 유일한 클래스입니다 (곧 String에도 권한이 부여됨). 다른 작업 (자동 정적 메서드 생성, 직렬화 처리 등)도 수행하지만 이론적으로는 코드를 사용하여 수행 할 수 있습니다. 단지 많은 상용구 일 뿐이며 일부 제약 조건은 하위 클래스 (예 : 특별한 서브 클래 싱 규칙) 그러나 열거 형의 특권 상태 없이는 결코 달성 할 수없는 것은 switch 문에 포함시키는 것입니다.
  • 객체 -모든 객체의 루트 (복제 및 finalize 메소드를 추가하는 것은 구현할 수있는 것이 아닙니다)
  • 참조 : WeakReference, SoftReference, PhantomReference
  • 스레드 -언어는 스레드를 시작하라는 특정 명령을 제공하지 않고 마술처럼 start () 메서드에 적용합니다.
  • Throwable -throw, throw 및 catch와 함께 작동 할 수있는 모든 클래스의 루트는 물론 Exception 대 ​​RuntimeException 및 Error에 대한 컴파일러 이해도입니다.
  • NullPointerException 및 athrow 이외의 다른 바이트 코드 명령에 의해 throw 될 수있는 ArrayIndexOutOfBounds와 같은 기타 예외.

인터페이스

  • Iterable- 향상된 for 루프에서 사용할 수있는 유일한 인터페이스

명예로운 언급은 다음과 같습니다.

  • java.lang.reflect. 배열 -Class 객체에 정의 된대로 새 배열을 만드는 것은 불가능합니다.
  • 주석 런타임시 인터페이스처럼 작동하는 특수 언어 기능입니다. Object에 대한 대체를 정의 할 수없는 것처럼 확실히 다른 Annotation 인터페이스를 정의 할 수 없습니다. 그러나 모든 기능을 구현하고 리플렉션이 아닌 다른 방법으로 검색 할 수 있습니다. 사실, 주석이 도입되기 전에는 많은 XML 기반 및 javadoc 태그 기반 구현이있었습니다.
  • ClassLoader- 바이트 코드 방식이 있지만 클래스를로드하는 언어 방식이 없기 때문에 JVM과 확실히 특권 관계가 있으므로 그런 방식으로 Array와 같습니다. 구현 세부 사항이지만 JVM에 의해 다시 호출되는 특별한 권한도 있습니다.
  • 직렬화 가능 -리플렉션을 통해 기능을 구현할 수 있지만 고유 한 권한이있는 키워드가 있으며 일부 시나리오에서 SecurityManager와 친밀 해지는 데 많은 시간을 할애합니다.

참고 : JNI (예 : IO)를 제공하는 항목은 목록에서 제외했습니다. 원하는 경우 항상 자체 JNI 호출을 구현할 수 있기 때문입니다. 그러나 특권 방식으로 JVM과 상호 작용하는 기본 호출은 다릅니다.

배열은 논란의 여지가 있습니다-그들은 Object를 상속하고 이해되는 계층 구조를 가지고 있습니다 (Object []는 String []의 상위 유형입니다). 그러나 그것들은 그 자체로 정의 된 클래스가 아니라 언어 기능입니다.


@Donal, 매우 사실입니다. 저는 런타임 주석을 생각하고 있었지만 소스 수준 주석은 실제로 그런 방식으로 수행되었습니다 (가장 주목할만한 xdoclet 또는 @deprecated가있는 코어 Java에서도)
Yishai

나는 원래 xdoclet 처리로 작성된 후 주석으로 변환 된 코드의 덤불을 통해 내 방식대로 싸우고 있습니다. 오, 내가 주석을 선호하는 방법 (적합한 maven 주문을 사용하더라도 순 효과는 동일합니다).
Donal Fellows

@ KK_07k11A0585, 컬렉션은 누구나 다른 방식으로 빌드 할 수있는 표준 API입니다 (사실 기본 요소를 중심으로 한 대체 구현과이를 향상시키는 매우 유명한 Google 프로젝트가 있습니다). 그들이 얻는 유일한 것은 대답에 언급 된 Iterable입니다. 그들은 확실히 자바 프로그래밍의 빵과 버터이지만 특별한 권한이없는 정규 클래스 일뿐입니다.
Yishai

@Yishai 응용 프로그램을 개발하는 동안 중요한 것은 데이터 관리입니다. 우리 모두는 다양한 방법으로 작업을 수행 할 수 있지만 최적화 된 방법은 메모리를 적게 차지하고 불필요한 참조를 적게 사용하는 것입니다. 컬렉션을 사용하여 우리는 이진 검색, 병합 정렬 등과 ​​같은 사전 정의 된 알고리즘을 제공하는 대량의 데이터를 정렬, 검색 및 비교할 수 있습니다. 또한 기술을 사용자 정의 할 수있는 비교기 및 비교 가능한 인터페이스를 제공합니다. 컬렉션 클래스는 자바에서 최고의 클래스가 아닐 수 있지만 의심 할 여지없이 영광스러운 자질의 클래스입니다.
KK_07k11A0585

1
어때 SecurityManager? 아니면 반영이나 직렬화와 관련된 것이 있습니까?
Antimony

19

Class, 물론이야. 자체 리터럴 ( StringBTW 와 공유하는 구별 )이 있으며 모든 반사 마법의 시작점입니다.


아, 좋은 지적입니다. 그렇다면 클래스 리터럴의 예는 무엇입니까? MyClass.class를 참조하고 있습니까?
aioobe 2010-08-11

4
@aioobe : 정확합니다. 참고도 등 int.class를, char.class, 가지고
마이클 Borgwardt


12
  1. 열거 형. 하위 클래스는 허용되지 않지만 컴파일러는 할 수 있습니다.
  2. java.util.concurrent 아래의 많은 것들은 JVM 지원없이 구현 될 수 있지만 훨씬 덜 효율적입니다.

1
익명으로 열거 형 (열거 형 값에 대한 방문자 패턴 impl.의 기본)을 하위 클래스화할 수 있습니다. 그러나 예, 열거 형을 완전히 하위 클래스화할 수는 없습니다. ;-)
Thierry

11

모든 Number 클래스 에는 Autoboxing 형식으로 약간의 마법이 있습니다.


부울과 캐릭터도 포함하는 프리미티브를 래핑하는 클래스를 의미합니다. 그러나 BigInteger는 제외합니다.
emory

1
@emory : 맞습니다. 단지 기본 래퍼 클래스입니다. 불행히도 BigInteger는 제외됩니다.
Bill the Lizard

10

중요한 클래스 가 언급되었으므로 몇 가지 인터페이스를 언급하겠습니다.

Iterable(1.5부터) 인터페이스 -이 객체가 foreach 루프에 참여할 수 있습니다 :

Iterable<Foo> iterable = ...;
for (Foo foo : iterable) {

}

Serializable인터페이스는 표준 인터페이스는 다른 매우 특별한 의미를 가지고 있습니다. 인터페이스에 정의되지 않은 경우에도 고려할 메서드를 정의 할 수 있습니다 (예 readResolve():). transient키워드의 동작에 영향을주는 언어 요소 Serializable구현합니다.


사실, 그것들은 인터페이스이기 때문에보기마다 "특별한"구현이 필요하지 않습니다. (Throwable과 유사합니다.)
aioobe

Serializable은 실제로 특별한 구현이 필요합니다. 두 가지 방법이있을 것으로 예상되는 인터페이스입니다 (이름을 잊어 버렸습니다 ... Google로 검색 할 수 있습니다 ...). 표준 인터페이스 체계에 필요하거나 정의되어 있지는 않습니다.
corsiKa 2010 년

@glowcoder : 그러나 Serializable의 모든 특수성은 Java 언어와 관련이 없으며 ObjectOutputStream 및 ObjectInputStream의 구현에만 관련이 있다고 주장 할 수 있습니다.
Michael Borgwardt

5
@Michael Borgwardt이있다 - transient키워드
Bozho

1
나는 그렇게 생각 Comparable하지 않는다 – 내부적 인 어떤 것도 관여하지 않는다. 당신은 쉽게 쓸 수있는 NewComparable새로운 NewArrays.sort(..)동일한 기능과 함께
Bozho

6
  1. Throwable , RuntimeException, 오류 AssertionError
  2. 참조 WeakReference, SoftReference, PhantomReference
  3. 열거 형
  4. 주석

좋은 목록입니다. +1, Annotation은 인터페이스이며 구현이 없습니다.
aioobe 2010-08-11

1
주석은 일반 인터페이스와는 다르게 컴파일러에서 처리됩니다. enum과 유사하게 모두 Annotation을 확장하며 컴파일러는이를 자동으로 수행합니다. JavaDoc of Annotation에서 : 모든 주석 유형으로 확장 된 공통 인터페이스입니다. 이 인터페이스를 수동으로 확장하는 인터페이스는 주석 유형을 정의하지 않습니다. 또한이 인터페이스는 자체적으로 주석 유형을 정의하지 않습니다. 따라서 일반 구문을 사용하여 주석을 만들 수 없으며 컴파일러를 변경하여 추가해야했습니다.
Andrei Fierbinteanu 2010 년



2

이것에 대해 확실하지 않습니다. 그러나 IO 개체를 수동으로 구현하는 방법을 생각할 수 없습니다.


당신 말이 맞습니다. 그들은 순수한 자바로 구현 될 수 없습니다. JNI를 통해 구현해야합니다 (시스템 호출을 수행해야하는 다른 클래스와 마찬가지로). 그러나 그 외에도 컴파일러 또는 jvm의 특별한 지원이 필요하지 않습니다.
aioobe

2

System수업 에는 마법이 있습니다 .

System.arraycopy 네이티브 코드에 대한 후크

public static native void arraycopy(Object array1, int start1, 
  Object array2, int start2, int length);

그러나...

/**
 * Private version of the arraycopy method used by the jit
 * for reference arraycopies
 */
private static void arraycopy(Object[] A1, int offset1,
  Object[] A2, int offset2, int length) {
   ...
}

1
대답의 두 번째 부분은 무엇을 의미합니까?
Pacerier

1

어설 션의 특수 처리가 언급되었으므로 글쎄요. 다음은 jvm에 의해 특별하게 처리되는 몇 가지 예외 유형입니다.

  • NullPointerException
  • ArithmeticException.
  • StackOverflowException
  • 모든 종류의 OutOfMemoryError
  • ...

예외는 특별하지 않지만 jvm은 특수한 경우에 예외를 사용하므로 자신의 jvm을 작성하지 않고 직접 구현할 수 없습니다. 나는 주변에 더 특별한 예외가 있다고 확신합니다.


0

이러한 클래스의 대부분은 실제로 컴파일러 또는 JVM의 '특별한'도움으로 구현되지 않습니다. 객체는 내부 JVM 구조를 찌르는 일부 네이티브를 등록하지만 자신의 클래스에 대해서도 그렇게 할 수 있습니다. (나는 이것이 의미론에 종속된다는 것을 인정한다. "JVM에 정의 된 네이티브 호출"은 특별한 JVM 지원으로 간주 될 수있다.)

/ is / 특별한 것은 이러한 내부 구조를 초기화하는 방법에 대한 'new'및 'throw'명령의 동작입니다.

주석과 숫자는 거의 완전히 이상합니다.


4
aioobe는 특별한 빌드를 지원하기 때문에 직접 구현할 수없는 클래스를 의미합니다. java.lang.Object 양식을 상속하지 않고는 유형 시스템의 루트로 고유 한 Object 클래스를 작성할 수 없습니다. 객체는 루트 클래스인지 확인하기 위해 컴파일러와 jvm 모두에서 특별한 지원을 제공합니다. 네이티브 호출만으로는이 문제를 해결할 수 없습니다.
josefx 2010-08-11
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.