Java获取和设置字段
示例
使用ReflectionAPI,可以在运行时更改或获取字段的值。例如,您可以在API中使用它,以根据某个因素(例如操作系统)来检索不同的字段。您也可以删除修饰符,例如final允许修饰最终的字段。
为此,您将需要以getField()如下所示的方式使用Class#方法:
// Get the field in class SomeClass "NAME". Field nameField = SomeClass.class.getDeclaredField("NAME"); // Get the field in class Field "modifiers". Note that it does not //需要是静态的 Field modifiersField = Field.class.getDeclaredField("modifiers"); //即使宣布为私有也允许任何人访问 modifiersField.setAccessible(true); // Get the modifiers on the "NAME" field as an int. int existingModifiersOnNameField = nameField.getModifiers(); //现有修饰符上的按位ANDNOTModifier.FINAL(16) // Readup here https://en.wikipedia.org/wiki/Bitwise_operations_in_C //如果不确定什么是按位运算。 int newModifiersOnNameField = existingModifiersOnNameField & ~Modifier.FINAL; //为非静态字段设置对象下的修饰符字段的值 modifiersField.setInt(nameField, newModifiersOnNameField); //将其设置为可访问。这将覆盖普通的Java //私有/受保护/程序包/等访问控制检查。 nameField.setAccessible(true); // Set the value of "NAME" here. Note the null argument. //修改静态字段时传递null,因为没有实例对象 nameField.set(null, "被反射砍死..."); //在这里我可以直接访问它。如果需要,请使用反射进行获取。(下面) System.out.println(SomeClass.NAME);
获取字段要容易得多。我们可以使用Field#get()及其变体来获取其值:
// Get the field in class SomeClass "NAME". Field nameField = SomeClass.class.getDeclaredField("NAME"); //设置为私有字段可访问 nameField.setAccessible(true); //传递null因为没有实例,还记得吗? String name = (String) nameField.get(null);
请注意以下几点:
使用Class#getDeclaredField时,可使用它来获取类本身中的字段:
class HackMe extends Hacked { public String iAmDeclared; } class Hacked { public String someState; }
在这里,HackMe#iAmDeclared是声明字段。但是,HackMe#someState不是声明的字段,因为它是从其超类Hacked继承的。