1field(字段)
- getField(name): 获取某个public的field(包括父类),在调用
getField()
方法时,如果根据给定的方法参数没有找到对应的变量,那么就会抛出NoSuchFieldException
- getDeclaredField(name): 获取当前类的某个field(不包括父类)
- getFields(): 获取所有public的field(包括父类)
- getDeclaredFields(): 获取当前类的所有field(不包括父类)
Field对象包含一个field的所有信息:
- getName():通过调用
Field
对象的getName()
方法获取它的变量名称 - getType():通过调用
Field
对象getType()
方法来获取一个变量的类型(如String, int等等) - getModifiers():获取修饰符,即public/private/static等修饰符的使用状况,还可以使用Modifier类中的isPublic、isPrivate或isFinal判断方法或构造器是否是public、private或final
Integer n = new Integer(123);
Class cls = n.getClass();
Field[] fs = cls.getFields();
for (Field f : fs) {
f.getName(); // field name
f.getType(); // field type
f.getModifiers(); // modifiers
}
获取field的值:
- get(Object)获取一个实例的该字段的值
Integer n = new Integer(123);
Class cls = n.getClass();
Field f = cls.getDeclaredField("value");
f.get(n);//123,相当于n.value
设置field的值:
- set(Object,Object)设置一个实例的该字段的值
Integer n = new Integer(123);
Class cls = n.getClass();
Field f = cls.getDeclaredField("value");
f.set(n,456);//相当于n.value = 456
2实例演示
public class Main {
public static void main(String[] args) throws Exception{
Student s = new Student();
Class cls = s.getClass();
Field f = cls.getDeclaredField("address");
//Field f = cls.getDeclaredField("number");//可以获取静态字段number
//printFieldInfo(f);
//setAccessible()可以强制变为可以访问
//setAccessible(true/false):表示启用和禁用安全检查的开关。
//当值为true时,指反射对象在使用时应该取消java语言访问检查
//值为false则只是反射的对象应该试试java语言访问检查。
//当值 设置为true时,不接受检查,可以提高反射的运行速度。
f.setAccessible(true);
System.out.println(f.get(s));//获取field的值
//System.out.println(f.get(null));//静态字段不需要获取实例,传入null
f.set(s,"shanghai");//设置field的值
//f.set(null,123);//静态字段不需要获取实例,传入null
s.hello();
}
static void printFieldInfo(Field f) {
// TODO Auto-generated method stub
System.out.println("field name:" + f.getName());
System.out.println("field type:" + f.getType());
System.out.println("field modifier:" + f.getModifiers());
System.out.println("is public?" + Modifier.isPublic(f.getModifiers()));
System.out.println("is protected?" + Modifier.isProtected(f.getModifiers()));
System.out.println("is private?" + Modifier.isPrivate(f.getModifiers()));
System.out.println("is static?" + Modifier.isStatic(f.getModifiers()));
System.out.println("is final?" + Modifier.isFinal(f.getModifiers()));
}
}
public class Person {
public int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Student extends Person implements Hello{
public static int number = 0;
public String name;
private String address = "beijing";
public Student() {
this("unNamed");
}
public Student(String name) {
this.name = name;
}
public void hello() {
System.out.println("Hi, "+name+" from " +address +"!");
}
}
public interface Hello {
public void hello();
}
3SecurityManager
setAccessible(true)可能会失败:
- 定义了SecurityManager
- SecurityManager的规则阻止对该Field设置accessible:例如,规则应用于所有java和javax开头的package的类
4总结
- Field对象封装了字段的所有信息
- 通过Class实例的方法可以获取Field实例:getField/getFields/getDeclaredField/getDeclaredFields
- 通过Field实例可以获取字段信息:getName/getType/getModifiers
- 通过Field实例可以读取或设置某个对象的字段:get(Object instance)/set(Object instance,Object fieldValue)
- 通过设置setAccessible(true)来访问非public字段