2015-08-22 4 views
7

Betrachten Sie diese Klasse:Iterate durch Werte in @IntDef, @StringDef oder jede @dEF Klasse

public class MyClassOfMystery { 

    public static final int NO_FLAGS = ~0; 
    public static final int FIRST_FLAG = 1; 
    public static final int SECOND_FLAG = 1 << 1; 
    public static final int THIRD_FLAG = 1 << 2; 
    public static final int FOURTH_FLAG = 1 << 3; 

    @Retention(RetentionPolicy.SOURCE) 
    @IntDef(flag = true, value = {NO_FLAGS, FIRST_FLAG, SECOND_FLAG, THIRD_FLAG, FOURTH_FLAG}) 
    public @interface MysteryFlags { } 

    ... set flags, get flags, and use flags stuff. 
} 

ich oft so etwas wie dieses erstellt haben, und festgestellt, dass es nützlich wäre, der Lage sein, durch alle iterieren Flaggen verfügbar in MysteryFlags.

Kann ich meine in MysteryFlags eingestellten Werte durchlaufen?

Dies ist, was ich versucht habe:


Diese gedruckte ANNOTATION: @java.lang.annotation.Retention(value=SOURCE):

for (Annotation annotation : Flag.class.getAnnotations()) { 
    Log.d(TAG, String.format("ANNOTATION: %s", String.valueOf(annotation))); 
} 

Dieser warf NPE auf einen Null-Array Zugriff

for (ExtraAction enm : Flag.class.getEnumConstants()) { 
    Log.d(TAG, String.format("ENUM: %s", String.valueOf(enm))); 
} 

Diese gedruckt wird nichts aus:

for (Field field : Flag.class.getFields()) { 
    Log.d(TAG, String.format("FIELD: %s", String.valueOf(field))); 
} 

und

for (Class<?> aClass : ExtraAction.class.getClasses()) { 
     Log.d(TAG, String.format("CLASS: %s", String.valueOf(aClass))); 
} 

Ich weiß, ich kann nur die Werte in einem Array hinzufügen und dadurch laufen, aber das erfordert eine andere Speicherung Array. Es ist das, was ich getan habe, frage mich aber immer noch, ob es einen besseren Weg gibt.

Antwort

6

Ich denke nicht, dass Sie es zur Laufzeit so abfragen können. Ihre @MysterFlags Annotation hat eine Aufbewahrungsrichtlinie von SOURCE, was bedeutet, dass sie vom Compiler verworfen wird. Außerdem hat die Annotation @IntDef eine Aufbewahrungsrichtlinie von CLASS, was bedeutet, dass sie durch Compilieren zustande kommt, aber nicht zur Laufzeit geht. Aus diesem Grund sehen Sie nur die Annotation @Retention in Ihrer ersten Schleife (diese Annotation hat eine Aufbewahrungsrichtlinie von RUNTIME).

+0

Sehr guter Punkt. –

+0

Könnte ich iterieren, wenn ich die Aufbewahrungsrichtlinie in Laufzeit ändere? –

+2

Wenn Sie versuchen, die Werte für '@ IntDef' zu betrachten, dann denke ich nicht. Sie können die Aufbewahrungsrichtlinie für diese Anmerkung nicht ändern. –