文档

Java™ 教程
隐藏目录
检索和解析字段修饰符
路径:反射API
课程:成员
章节:字段

检索和解析字段修饰符

字段声明可能包含几个修饰符:

方法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来检索任何运行时注解。有关获取注解的示例,请参见检查类的修饰符和类型部分。


上一页: 获取字段类型
下一页: 获取和设置字段值