Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本引入的改进,并且可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及其后续版本中更新的语言功能的概述。
请参阅JDK发布说明,了解有关所有JDK版本的新功能、增强功能和已删除或弃用选项的信息。
字段声明可能包含几个修饰符:
public
、protected
和private
transient
和volatile
static
final
方法Field.getModifiers()
可用于返回表示字段的已声明修饰符集合的整数。这个整数中表示修饰符的位在java.lang.reflect.Modifier
中定义。
示例
演示了如何查找具有给定修饰符的字段。它还通过调用FieldModifierSpy
Field.isSynthetic()
和Field.isEnumCostant()
来确定定位的字段是否是合成的(由编译器生成的)或枚举常量。
import java.lang.reflect.Field; import java.lang.reflect.Modifier; import static java.lang.System.out; enum Spy { BLACK , WHITE } public class FieldModifierSpy { volatile int share; int instance; class Inner {} public static void main(String... args) { try { Class<?> c = Class.forName(args[0]); int searchMods = 0x0; for (int i = 1; i < args.length; i++) { searchMods |= modifierFromString(args[i]); } Field[] flds = c.getDeclaredFields(); out.format("在类 '%s' 中包含修饰符的字段: %s%n", c.getName(), Modifier.toString(searchMods)); boolean found = false; for (Field f : flds) { int foundMods = f.getModifiers(); // 要求所有请求的修饰符都存在 if ((foundMods & searchMods) == searchMods) { out.format("%-8s [ synthetic=%-5b enum_constant=%-5b ]%n", f.getName(), f.isSynthetic(), f.isEnumConstant()); found = true; } } if (!found) { out.format("找不到匹配的字段%n"); } // 实际代码应该更优雅地处理这个异常 } catch (ClassNotFoundException x) { x.printStackTrace(); } } private static int modifierFromString(String s) { int m = 0x0; if ("public".equals(s)) m |= Modifier.PUBLIC; else if ("protected".equals(s)) m |= Modifier.PROTECTED; else if ("private".equals(s)) m |= Modifier.PRIVATE; else if ("static".equals(s)) m |= Modifier.STATIC; else if ("final".equals(s)) m |= Modifier.FINAL; else if ("transient".equals(s)) m |= Modifier.TRANSIENT; else if ("volatile".equals(s)) m |= Modifier.VOLATILE; return m; } }
示例输出如下:
$ java FieldModifierSpy FieldModifierSpy volatile 类'FieldModifierSpy'中包含修饰符的字段:volatile share [ synthetic=false enum_constant=false ] $ java FieldModifierSpy Spy public 类'Spy'中包含修饰符的字段:public BLACK [ synthetic=false enum_constant=true ] WHITE [ synthetic=false enum_constant=true ] $ java FieldModifierSpy FieldModifierSpy\$Inner final 类'FieldModifierSpy$Inner'中包含修饰符的字段:final this$0 [ synthetic=true enum_constant=false ] $ java FieldModifierSpy Spy private static final 类'Spy'中包含修饰符的字段:private static final $VALUES [ synthetic=true enum_constant=false ]
请注意,尽管某些字段没有在原始代码中声明,但仍然会被报告。这是因为编译器会生成一些在运行时需要的合成字段。为了测试一个字段是否为合成字段,示例代码调用了Field.isSynthetic()
。合成字段的集合取决于编译器,但常用的字段包括用于内部类(即非静态成员类)引用最外层封闭类的this$0
以及枚举类用于实现隐式定义的静态方法values()
的$VALUES
。合成类成员的名称未指定,并且在所有编译器实现或版本中可能不相同。这些和其他合成字段将包含在Class.getDeclaredFields()
返回的数组中,但由于合成成员通常不是public
,所以不能通过Class.getField()
来识别。
由于Field
实现了接口java.lang.reflect.AnnotatedElement
,因此可以使用java.lang.annotation.RetentionPolicy.RUNTIME
来检索任何运行时注解。有关获取注解的示例,请参见检查类的修饰符和类型部分。