39 Stimmen

Erstellen einer Annotation-Instanz mit Standardwerten in Java

Wie kann ich eine Instanz der folgenden Anmerkung erstellen (wobei alle Felder auf ihren Standardwert gesetzt werden)?

    @Retention( RetentionPolicy.RUNTIME )
    public @interface Settings {
            String a() default "AAA";
            String b() default "BBB";
            String c() default "CCC";
    }

Ich habe versucht new Settings() , aber das scheint nicht zu funktionieren...

41voto

Ralph Punkte 114913

Um eine Instanz zu erstellen, müssen Sie eine Klasse erstellen, die implementiert:

Zum Beispiel: public class MySettings implements Annotation, Settings

Sie müssen jedoch besonders auf die richtig Umsetzung von equals y hashCode nach der Annotation Schnittstelle. http://download.oracle.com/javase/1.5.0/docs/api/java/lang/annotation/Annotation.html

Wenn Sie dies nicht immer wieder neu implementieren wollen, schauen Sie sich die javax.enterprise.util.AnnotationLiteral Klasse. Dies ist Teil der CDI (Context Dependency Injection)-API. (@see code)

Um die Standardwerte zu erhalten, können Sie die von akuhn (früher bekannt als Adrian) beschriebene Methode verwenden. Settings.class.getMethod("a").getDefaultValue()

38voto

akuhn Punkte 26637

Sie können keine Instanz erstellen, aber zumindest die Standardwerte abrufen

Settings.class.getMethod("a").getDefaultValue()
Settings.class.getMethod("b").getDefaultValue()
Settings.class.getMethod("c").getDefaultValue()

Und dann könnte ein dynamischer Proxy verwendet werden, um die Standardwerte zurückzugeben. Das ist, soweit ich weiß, die Art und Weise, wie Annotationen auch von Java selbst gehandhabt werden.

class Defaults implements InvocationHandler {
  public static <A extends Annotation> A of(Class<A> annotation) {
    return (A) Proxy.newProxyInstance(annotation.getClassLoader(),
        new Class[] {annotation}, new Defaults());
  }
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
    return method.getDefaultValue();
  }
}

Settings s = Defaults.of(Settings.class);
System.out.printf("%s\n%s\n%s\n", s.a(), s.b(), s.c());

28voto

emory Punkte 10495

Ich habe kompiliert und mit zufriedenstellenden Ergebnissen ausgeführt.

class GetSettings {
    public static void main (String[] args){
      @Settings final class c { }
      Settings settings = c.class.getAnnotation(Settings.class);
      System.out.println(settings.aaa());
    }
}

3voto

ex0b1t Punkte 1202

Hatte das gleiche Problem, ich habe es wie folgt gelöst.

public static FieldGroup getDefaultFieldGroup() {
    @FieldGroup
    class settring {
    }
    return settring.class.getAnnotation(FieldGroup.class);
}

2voto

mindas Punkte 25933

Es gibt eine alternative Lösung, wenn Sie es sich leisten können, die Karosserie von Settings Klasse:

@Retention( RetentionPolicy.RUNTIME )
public @interface Settings {
        String DEFAULT_A = "AAA";
        String DEFAULT_B = "BBB";
        String DEFAULT_C = "CCC";

        String a() default DEFAULT_A;
        String b() default DEFAULT_B;
        String c() default DEFAULT_C;
}

Dann können Sie einfach auf Settings.DEFAULT_A (ja, ein besserer Name wäre hilfreich!).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X