遍历@IntDef、@StringDef 或任何@Def class 中的值
Iterate through values in @IntDef, @StringDef or any @Def class
考虑这个 class:
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.
}
我经常创建这样的东西,并发现能够遍历 MysteryFlags
中可用的所有标志会很有用。
我可以遍历 MysteryFlags
中设置的值吗?
这是我试过的:
这打印了 ANNOTATION: @java.lang.annotation.Retention(value=SOURCE)
:
for (Annotation annotation : Flag.class.getAnnotations()) {
Log.d(TAG, String.format("ANNOTATION: %s", String.valueOf(annotation)));
}
这在空数组访问上引发了 NPE
for (ExtraAction enm : Flag.class.getEnumConstants()) {
Log.d(TAG, String.format("ENUM: %s", String.valueOf(enm)));
}
这些没有打印出任何东西:
for (Field field : Flag.class.getFields()) {
Log.d(TAG, String.format("FIELD: %s", String.valueOf(field)));
}
和
for (Class<?> aClass : ExtraAction.class.getClasses()) {
Log.d(TAG, String.format("CLASS: %s", String.valueOf(aClass)));
}
我知道我可以将值添加到一个数组并遍历它,但这需要存储另一个数组。我已经这样做了,但仍然想知道是否有更好的方法。
我认为您无法在运行时那样查询它。您的 @MysterFlags
注释具有 SOURCE
的保留策略,这意味着它将被编译器丢弃。此外,@IntDef
注释具有 CLASS
的保留策略,这意味着它可以通过编译,但不会进入运行时。这就是为什么您在第一个循环中只看到 @Retention
注释(该注释的保留策略为 RUNTIME
)。
好吧,这现在可能有点老了 - 但我遇到了类似的问题,我找到的解决方案是:
MysteryFlags.class.getDeclaredFields()
它将return声明的所有定义。
如果我们在 @interface
本身内声明我们的字段,则可以做出 妥协 。
@Retention(RetentionPolicy.SOURCE)
@IntDef({MysteryFlags.NO_FLAGS, MysteryFlags.FIRST_FLAG, MysteryFlags.SECOND_FLAG, MysteryFlags.THIRD_FLAG, MysteryFlags.FOURTH_FLAG})
public @interface MysteryFlags {
// Note that all fields declared in an interface are implicitly public static final
int NO_FLAGS = ~0;
int FIRST_FLAG = 1;
int SECOND_FLAG = 1 << 1;
int THIRD_FLAG = 1 << 2;
int FOURTH_FLAG = 1 << 3;
}
在 MisteryFlags.class
上调用 getFields()
时,将返回注释中声明的所有字段。
但是,这意味着 @interface
中未在 @IntDef
中定义的任何字段也将被返回。 IMO,如果按照严格的协议实施,这会很有效。
考虑这个 class:
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.
}
我经常创建这样的东西,并发现能够遍历 MysteryFlags
中可用的所有标志会很有用。
我可以遍历 MysteryFlags
中设置的值吗?
这是我试过的:
这打印了 ANNOTATION: @java.lang.annotation.Retention(value=SOURCE)
:
for (Annotation annotation : Flag.class.getAnnotations()) {
Log.d(TAG, String.format("ANNOTATION: %s", String.valueOf(annotation)));
}
这在空数组访问上引发了 NPE
for (ExtraAction enm : Flag.class.getEnumConstants()) {
Log.d(TAG, String.format("ENUM: %s", String.valueOf(enm)));
}
这些没有打印出任何东西:
for (Field field : Flag.class.getFields()) {
Log.d(TAG, String.format("FIELD: %s", String.valueOf(field)));
}
和
for (Class<?> aClass : ExtraAction.class.getClasses()) {
Log.d(TAG, String.format("CLASS: %s", String.valueOf(aClass)));
}
我知道我可以将值添加到一个数组并遍历它,但这需要存储另一个数组。我已经这样做了,但仍然想知道是否有更好的方法。
我认为您无法在运行时那样查询它。您的 @MysterFlags
注释具有 SOURCE
的保留策略,这意味着它将被编译器丢弃。此外,@IntDef
注释具有 CLASS
的保留策略,这意味着它可以通过编译,但不会进入运行时。这就是为什么您在第一个循环中只看到 @Retention
注释(该注释的保留策略为 RUNTIME
)。
好吧,这现在可能有点老了 - 但我遇到了类似的问题,我找到的解决方案是:
MysteryFlags.class.getDeclaredFields()
它将return声明的所有定义。
如果我们在 @interface
本身内声明我们的字段,则可以做出 妥协 。
@Retention(RetentionPolicy.SOURCE)
@IntDef({MysteryFlags.NO_FLAGS, MysteryFlags.FIRST_FLAG, MysteryFlags.SECOND_FLAG, MysteryFlags.THIRD_FLAG, MysteryFlags.FOURTH_FLAG})
public @interface MysteryFlags {
// Note that all fields declared in an interface are implicitly public static final
int NO_FLAGS = ~0;
int FIRST_FLAG = 1;
int SECOND_FLAG = 1 << 1;
int THIRD_FLAG = 1 << 2;
int FOURTH_FLAG = 1 << 3;
}
在 MisteryFlags.class
上调用 getFields()
时,将返回注释中声明的所有字段。
但是,这意味着 @interface
中未在 @IntDef
中定义的任何字段也将被返回。 IMO,如果按照严格的协议实施,这会很有效。