2009-09-22 44 views
157

Hoy quería crear mi primera interfaz de anotación siguiente this documentation y me dieron el error del compilador "no válido para el tipo de miembro de la anotación":¿Qué tipos se pueden usar para miembros de anotación Java?

public @interface MyAnnotation { 
    Object myParameter; 
    ^^^^^^ 
} 

Obviamente Object no se puede utilizar como tipo de un miembro de anotación. Lamentablemente, no pude encontrar ninguna información sobre qué tipos se pueden usar en general.

Esto lo descubrió usando ensayo y error:

String --> Valid

int --> Valid

Integer --> Invalid (Surprisingly)

String[] --> Valid (Surprisingly)

Object --> Invalid

Tal vez alguien puede arrojar algo de luz sobre lo que realmente se permiten los tipos y por qué.

+0

posiblemente varíe por anotación - por favor muestre el código que está tratando de escribir. – djna

+2

Agregado a la pregunta. Pero no creo que eso varíe –

Respuesta

226

Es especificado por section 9.6.1 of the JLS. Los tipos de miembro anotación debe ser uno de:

  • primitiva
  • cadena
  • Clase
  • un Enum
  • otra anotación
  • una matriz de cualquiera de los anteriores

Parece restrictivo, pero sin duda hay razones para ello.

También tenga en cuenta que las matrices multidimensionales (por ejemplo, String[][]) están implícitamente prohibidas por la regla anterior.

+17

¿Cómo se encuentran esas páginas/documentos? Juro google cada vez antes de preguntar en StackOverlow y en muchas preguntas de Java, alguien publica un enlace al JSL que responde a mi pregunta. ¿Por qué no encuentro esas páginas a través de Google? –

+8

El JLS no es muy amigable para Google. Solo necesitas saber que está ahí. – skaffman

+1

la misma información también está disponible en la guía de anotaciones en el sitio de Sun (no encontró que Google): http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html – wds

53

Estoy de acuerdo con Skaffman para los tipos disponibles.

Restricción adicional: tiene que ser una constante en tiempo de compilación.

Por ejemplo, están prohibidos los siguientes:

@MyAnnot("a" + myConstantStringMethod()) 
@MyAnnot(1 + myConstantIntMethod()) 
10

El concepto de anotaciones encaja muy bien con el diseño de mi proyecto, hasta que se dio cuenta de que no puede tener tipos de datos complejos en la anotación. Lo solucioné usando la clase de lo que quería crear una instancia en lugar de un objeto instanciado de esa clase. No es perfecto, pero java rara vez lo es.

@interface Decorated { Class<? extends PropertyDecorator> decorator() } 

interface PropertyDecorator { String decorate(String value) } 

class TitleCaseDecorator implements PropertyDecorator { 
    String decorate(String value) 
} 

class Person { 
    @Decorated(decorator = TitleCaseDecorator.class) 
    String name 
} 
15

También no se olvide de que anotaciones mismos pueden ser parte de una definición de anotación. Esto permite anidar anotaciones simples, lo que es útil en casos en los que le gustaría tener una anotación presente muchas veces.

Por ejemplo:

@ComplexAnnotation({ 
    @SimpleAnnotation(a="...", b=3), 
    @SimpleAnnotation(a="...", b=3), 
    @SimpleAnnotation(a="...", b=3) 
}) 
public Object foo() {...} 

donde SimpleAnnotation es

@Target(ElementType.METHOD) 
public @interface SimpleAnnotation { 
    public String a(); 
    public int b(); 
) 

y ComplexAnnotation es

@Target(ElementType.METHOD) 
public @interface ComplexAnnotation { 
    public SimpleAnnotation[] value() default {}; 
) 

ejemplos tomados de: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

+3

Con Java 8 '@ Repeatable', ya no es necesario. – Mordechai

Cuestiones relacionadas