java - ver - ¿Por qué los valores de cadena de anotación no están internados?




textos invisibles en autocad (2)

Los literales de cadena están internados, pero las anotaciones están sujetas a análisis y se almacenan en matrices de bytes. Si miras la clase java.lang.reflect.Method puedes ver esto:

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

Eche también un vistazo al método public Object getDefaultValue() de la misma clase para ver cómo se llama a AnnotationParser. El flujo continúa hasta aquí AnnotationParser.parseConst y entrar

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

El método ConstantPool.getUTF8At es un delegado de un método nativo. Puede ver el código aquí implementación nativa getUFT8At . La constante analizada nunca se interna y nunca se recupera de StringTable (donde la cadena está interna).

Creo que podría ser una elección de implementación. El internamiento se ha creado para hacer una comparación más rápida entre el literal de cadena y, por lo tanto, se usa solo para el uso literal del interns en la implementación del método.

https://code.i-harness.com

El siguiente fragmento imprime 4 códigos hash distintos, a pesar de reutilizar una cadena constante y literal. ¿Por qué los valores de cadena no están internados en elementos de anotación?

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() {}
}

Es porque tiene acceso a la anotación en tiempo de ejecución y de acuerdo con las especificaciones de Java - Ejemplo 3.10.5-1. Literales de cuerda , las cuerdas son de nueva creación y, por lo tanto, distintas.

Todas las cadenas literales y las expresiones constantes con valores de cadena en tiempo de compilación se internan automáticamente

En su caso, el valor de test1 se calculará en tiempo de ejecución a partir del método de valor nativo () (consulte el atributo AnnotationDefault ).

String value() default CONSTANT;

Otros casos también se computarán en tiempo de ejecución.

Cuando obtienes un valor de la anotación tienes que realizar pasantía explícitamente

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




string-interning