Jakie typy mogą być używane dla członków adnotacji Java?

Dzisiaj chciałem stworzyć swój pierwszy interfejs adnotacji po tej dokumentacji i dostałem błąd kompilatora

Invalid type for annotation member":
public @interface MyAnnotation {
    Object myParameter;
    ^^^^^^
}

Oczywiście Object nie może być użyty jako Typ elementu adnotacji. Niestety nie udało mi się znaleźć żadnych informacji, które typy mogą być używane w ogóle.

To odkryłem metodą prób i błędów:

  • String → Valid
  • int → Valid
  • Integer → Invalid (Zaskakująco)
  • String[] → Valid (Zaskakująco)
  • Object → Invalid

Być może ktoś może rzucić trochę światła na to, które typy są rzeczywiście dozwolone i dlaczego.

Author: Daniel Rikowski, 2009-09-22

4 answers

Jest określony przez Sekcja 9.6.1 JLS . Typy członów adnotacji muszą być jednym z:

  • prymitywne
  • String
  • an Enum
  • kolejna Adnotacja
  • klasa
  • Tablica dowolnego z powyższych
Wydaje się to restrykcyjne, ale bez wątpienia są ku temu powody.

Należy również zauważyć, że tablice wielowymiarowe (np. String[][]) są domyślnie zabronione przez powyższą regułę.

Tablice klas nie są dozwolone w sposób opisany w ta odpowiedź .

 337
Author: skaffman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Zgadzam się ze Skaffmanem co do dostępnych typów.

Dodatkowe ograniczenie : musi to być stała czasu kompilacji .

Na przykład, następujące są zabronione:

@MyAnnot("a" + myConstantStringMethod())
@MyAnnot(1 + myConstantIntMethod())
 58
Author: KLE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-12 03:32:37

Nie zapominaj również, że same adnotacje mogą być częścią definicji adnotacji . Pozwala to na proste zagnieżdżanie adnotacji-przydatne w przypadkach, gdy chcesz, aby jedna adnotacja była obecna wiele razy.

Na przykład:

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

Gdzie SimpleAnnotation jest

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

I ComplexAnnotation jest

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

Przykłady zaczerpnięte z: http://web.archive.org/web/20131216093805/https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

(oryginalny URL: https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations)

 34
Author: fikovnik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-10 08:01:01

Koncepcja adnotacji bardzo dobrze pasuje do projektu mojego projektu, dopóki nie zdałem sobie sprawy, że nie można mieć złożonych typów danych w adnotacji. Obejrzałem to, używając klasy tego, co chciałem utworzyć instancję, a nie instancyjnego obiektu tej klasy. Nie jest idealny, ale java rzadko jest.

@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
}
 13
Author: Josh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-02 20:38:44