2016-12-24 13 views
-1

저는 자바 바이트 코드에 대한 개인 연구를 해왔고 조금 이상하게 보입니다. this class을 디 컴파일하면 정수 풀에서 Class.forName()이라는 말을 찾을 수 있습니다. 그러나이 방법에 대한 소스 코드에는 참조가 없습니다.Class.forName이이 클래스의 바이트 코드에 나타나는 이유는 무엇입니까?

이 코드에 대해 javac에서 동적으로 클래스를로드하는 약간의 코드를 생성한다고 가정합니다. 그러나 이것이 왜 발생하는지 잘 모르겠습니다. 그것은 비효율적 인 것으로 생각되지만 주로 왜 이런 일이 발생하는지 궁금합니다.

+5

놀랍게도 Class.forName()이 포함 된 클래스와 디 컴파일 결과를 게시하지 않는 이유는 무엇입니까? 그것은 우리가 짐작할 필요가 없도록합니다. –

+0

내가 이것을 만들었을 때 "내 질문에 답하십시오"란에 체크하는 것을 잊어 버렸습니다. 나는 질문을 작성했는데 javap이 아마 왜 그런 일이 일어나고 있는지 지적 할 수 있었다. 나는 그것을 가로 질러 온 다른 누군가를 위해 그것을 게시 할 것이라고 생각했다. – monitorjbl

+0

Java 1.4가 2008 년 10 월 30 일에 끝났을 때인 2016 년 12 월 25 일에 *** Java 1.4 *** 질문에 자발적으로 응답합니다 (http://www.oracle.com/ technetwork/java/javase/index-jsp-138567.html), 8 년 전에? [ 'Self-Learner'] (http://stackoverflow.com/help/badges/14/self-learner) 배지에 절실히 필요합니까? 이 질문/답변은 너무 쓸모 없기 때문에 두 가지 모두에 * "유용하지 않음"*해야합니다. – Andreas

답변

2

javap로 코드를 분해 후, 나는 소스 코드에 존재하지 않는 방법이 나타났습니다 : 그것은 버전 < JDK1.5 용으로 컴파일 된 바이트 코드에서 생성되는 다음과 같습니다

static java.lang.Class class$(java.lang.String); 
    Code: 
    0: aload_0 
    1: invokestatic #1     // Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; 
    4: areturn 
    5: astore_1 
    6: new   #3     // class java/lang/NoClassDefFoundError 
    9: dup 
    10: invokespecial #4     // Method java/lang/NoClassDefFoundError."<init>":()V 
    13: aload_1 
    14: invokevirtual #5     // Method java/lang/NoClassDefFoundError.initCause:(Ljava/lang/Throwable;)Ljava/lang/Throwable; 
    17: athrow 
    Exception table: 
    from to target type 
     0  4  5 Class java/lang/ClassNotFoundException 

코드 [1]에서 참조되는 클래스 리터럴이있을 때마다. 기본적으로,이 :

if (getClass() == Level.class) {} 

이로 바뀝니다 :

if (getClass() == class$("org.apache.log4j.Level")) {} 

class$()은 다음과 같습니다

static Class class$(java.lang.String className) { 
    try { 
     return Class.forName(className); 
    } catch (ClassNotFoundException e) { 
     throw new NoClassDefFoundError(); 
    } 
} 

분명히 JDK1.5에서 ldc_w 명령은로드 할 수있는 기능을 받았다 클래스 상수와 class$() 메서드는 더 이상 필요하지 않습니다.

+0

사실, ldc는 동일하게 유지되었으므로 class_info 상수를 참조 할 수있는 기능이 늘어났습니다. – Antimony

+0

'ldc_w'는 256 개 이상의 상수 풀 항목 (또는 첫 번째 항목을 지나치는 항목)을 더 구체적으로 지정하기 위해'ldc'의 특별한 변형입니다. 둘 다 Java 5부터'Class' 엔트리를 참조 할 수 있습니다 (자바 7 이후'MethodType' 또는'MethodHandle'을 참조 할 수 있으며, 지원되는 엔트리 유형 목록은 앞으로 커질 수 있습니다). Java 5 이전 코드의 정확한 레이아웃은 컴파일러에 따라 다릅니다. 어떤 컴파일러는 매번'forName' 호출을 피하기 위해'static' 필드에'Class'를 캐쉬 할 코드를 생성합니다. – Holger