下面的代码片段打印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() {}
}
发布于 2016-06-17 20:38:28
字符串字面值是固定的,但注释需要进行解析,并将其存储在字节数组中。如果您查看java.lang.reflect.Method
类,您可以看到:
private byte[] annotations;
private byte[] parameterAnnotations;
private byte[] annotationDefault;
还可以查看同一个类的方法public Object getDefaultValue()
,以了解AnnotationParser是如何调用的。这个流程一直持续到这里AnnotationParser.parseConst和enter in
case 's':
return constPool.getUTF8At(constIndex);
方法ConstantPool.getUTF8At
是本机方法的委托。你可以在这里看到native implementation getUFT8At的代码。解析的常量永远不会被内嵌,也永远不会从StringTable (字符串被内套的地方)中检索到。
我认为这可能是一种实现的选择。Interning是为了更快地比较字符串文字而创建的,因此仅用于在方法实现中使用的interning文字。
https://stackoverflow.com/questions/37853188
复制相似问题