2014-07-18 4 views
2

익명의 Java 클래스는 런타임에 컴파일러에서 미리 생성합니까?런타임에 Java 익명 클래스가 생성됩니까?

Java 문서 (They are like local classes except that they do not have a name)에 따르면, 내 생각에 그들은 미리 생성 될 것입니다. 당신이 당신의 근원을 인용 할 수 있거나 그런 것을 시험하는 방법을 안다면 저에게 알려주십시오!

답변

11

컴파일러에서 생성했습니다. 일부 코드를 컴파일하고 디스크에 무엇이 있는지 살펴봄으로써 볼 수 있습니다. 결국 Foo$1.class과 같은 것으로 끝날 것입니다. 여기서 Foo은 익명 메소드가 포함 된 클래스입니다. 예를 들어

:

public class Test { 
    public static void main(String[] args) { 
     Runnable runnable = new Runnable() { 
      @Override public void run() { 
       System.out.println("Hi"); 
      } 
     }; 
    } 
} 

> javac Test.java 
> dir Test*.class 
Test.class 
Test$1.class 

> javap -c Test$1 

Compiled from "Test.java" 
final class Test$1 implements java.lang.Runnable { 
    Test$1(); 
    Code: 
     0: aload_0 
     1: invokespecial #1     // Method java/lang/Object."<init>":()V 
     4: return 

    public void run(); 
    Code: 
     0: getstatic  #2     // Field java/lang/System.out:Ljava/io/PrintStream; 
     3: ldc   #3     // String Hi 
     5: invokevirtual #4     // Method java/io/PrintStream.println[...] 
     8: return 
} 

가 늘어나는만큼 JVM에 관한 한, 그들은 단지 일반 클래스입니다. 관련있는 인코딩 인스턴스와 같이 컴파일러에서 추가 한 다양한 언어 기능은 참조 할 수없는 이름을 사용하여 추가 메서드, 생성자 매개 변수 및 효과적으로 숨겨진 필드를 통해 구현됩니다.

생성 된 클래스에 이름이 없다는 것은 아닙니다. 실제로는 수동 코드를 사용하지 않는 것이 좋습니다. JLS 3.8에서 :

은 "자바 문자"

는 ASCII 밑줄 역사적인 이유로 대문자와 소문자 ASCII 라틴어 문자 AZ (\ u0041-의 \의 u005a), 그리고 AZ (\ u0061-의 \의 u007a) 등을 포함 (_, 또는 \ u005f)와 달러 기호 ($, 또는 \ u0024)를 사용하십시오. $ 기호는 기계적으로 생성 된 소스 코드에서만 사용되거나 드물게 레거시 시스템에서 기존 이름에 액세스하는 경우에는 사용하지 않아야합니다. 이론에 따라서

당신은 소스 코드에 액세스 Test$1 -하지만 javac 나는 아직 fathomed하지 않은 방법으로, 그렇게하지 못할 것으로 보인다. (클래스 파일의 메타 데이터를 사용하여 익명의 내부 클래스에서 컴파일되었는지 확인합니다.) 따라서 언어 관점에서 익명으로 처리됩니다.

+0

답변에 만족하지 않는 사용자 @riamu의 의견 : "생성 된 클래스에는 이름이 없습니다. 실제로는 Java에서 유효한 식별자가 아닌 이름입니다. 언어 관점에서 보면 익명으로 처리됩니다. " 필자가 취한 이유는 그의 예제에서 생성 된 클래스 이름 인 Foo $ 1, *이 Java에서 유효한 식별자이기 때문에 같은 디렉토리에서 Foo $ 1이라는 다른 클래스를 생성하면 오류가 생성 될 수 있기 때문입니다. 결론적으로 말하면 적어도 내가 알 수있는 한 "효과적으로 익명으로"생성 된 이름은 없습니다. – GhostCat

+0

@GhostCat : 감사합니다. 편집했습니다. –

4

익명 클래스의 바이트 코드는 컴파일 할 때 만들어집니다. 컴파일 된 클래스 파일을 확인하기 만하면됩니다. 익명 클래스는 뒤에 오는 클래스의 이름 뒤에 $ 기호와 함께 증가하는 이름이 붙습니다.