2016-06-16 8 views
20

다음 스 니펫은 문자열 상수 및 리터럴을 재사용 함에도 불구하고 4 개의 고유 한 해시 코드를 인쇄합니다. 주석 요소에 문자열 값이 포함되지 않는 이유는 무엇입니까?주석 문자열 값이 인턴으로 처리되지 않는 이유는 무엇입니까?

public class Foo { 
    @Retention(RetentionPolicy.RUNTIME) 
    @interface Bar { 
     String CONSTANT = "foo"; 

     String value() default CONSTANT; 
    } 

    public static void main(String[] args) throws Exception { 
     System.out.println(System.identityHashCode(Bar.CONSTANT)); 
     System.out.println(System.identityHashCode(Foo.class.getMethod("test1").getAnnotation(Bar.class).value())); 
     System.out.println(System.identityHashCode(Foo.class.getMethod("test2").getAnnotation(Bar.class).value())); 
     System.out.println(System.identityHashCode(Foo.class.getMethod("test3").getAnnotation(Bar.class).value())); 
    } 

    @Bar 
    public void test1() {} 

    @Bar("foo") 
    public void test2() {} 

    @Bar(Bar.CONSTANT) 
    public void test3() {} 
} 
+0

주석 문자열 리터럴 코드의 일부가 아닌 및 코드에서 문자열 리터럴과 같은 규칙이 적용되지 않습니다 인턴 수행해야 주석에서 값을 얻을 때 , 그래서 그들이 합쳐 져야하는 이유가 정말로 없습니다. – EJP

답변

10

문자열 리터럴은 허용되지만 주석은 구문 분석 대상이며 바이트 배열로 저장됩니다. 당신이 클래스를 보면 당신이 볼 수 java.lang.reflect.Method :

private byte[]    annotations; 
private byte[]    parameterAnnotations; 
private byte[]    annotationDefault; 

또한 테이크 같은 클래스의 방법 public Object getDefaultValue() 봐가 AnnotationParser를 호출하는 방법을 참조하십시오. 흐름은 여기 AnnotationParser.parseConst까지 계속하는 방법 ConstantPool.getUTF8At는 네이티브 메소드에 위양

case 's': 
    return constPool.getUTF8At(constIndex); 

에 입력합니다. 이 코드는 여기 native implementation getUFT8At에서 볼 수 있습니다. 파싱 ​​된 상수는 결코 구속되지 않으며 StringTable (문자열이 인 텐트되는 곳)에서 검색되지 않습니다.

구현의 선택이 될 수 있다고 생각합니다. 인터링은 String 리터럴 간의보다 빠른 비교를 위해 만들어 졌으므로 메소드 구현에 사용할 수있는 리터럴을 인턴하기위한 용도로만 사용됩니다.

4

런타임시 주석에 액세스하고 java spec - Example 3.10.5-1. String Literals에 따라 문자열이 새로 작성되므로 별개입니다.

모든 리터럴 문자열과 문자열 값 상수 표현이 자동으로 경우

을 구금되어 컴파일 시간 test1의 값은 기본 값에서 런타임에 계산됩니다() 메소드 (AnnotationDefault attribute보고).

다른 경우도 런타임에 계산됩니다.

당신은 당신이 명시 적으로

String poolString = Foo.class.getMethod("test1").getAnnotation(Bar.class).value().intern(); 
System.out.println(poolString == Bar.CONSTANT);