Java反射访问属性

反射访问字段

对于任何一个Object实例,只要我们获取了JVM中与之对应的Class实例,就可以通过该实例获取到该Object实例的一切信息。

Class类提供了一下几个方法来获取字段:
  • Field getField(String name):通过字段名获取public修饰的字段(包括父类继承的字段)
  • Field getDeclaredField(String name):通过字段名获取当前类中的字段(不包括父类)
  • Field[] getFields():获取所有public修饰的字段(包括父类)
  • Field[] getDeclaredFields():获取该类中所有字段(不包括父类)
public class ReflectField{
	public static void main(String[] args){
		Class stdClazz = Student.class;
		//获取当前类public字段
		System.out.println(stdClazz.getField("score"))
		//获取父类的public字段
		System.out.println(stdClazz.getField("name"))
		//获取private字段
		System.out.println(stdClazz.getDeclaredField("grade"))
	}
}

class Student extends Person{
	public int scroe;//分数
	private int grade;//年级
	
	public Student(String name) {
        super(name);
    }
}

class Person{
	public String name;//姓名
	
	public Person(String name) {
        this.name = name;
    }
}

输出结果:

public int com.example.factory_compiler.reflect.Student.score
public java.lang.String com.example.factory_compiler.reflect.Person.name
private int com.example.factory_compiler.reflect.Student.grade
一个Field对象包含了一个字段的所有信息:
  • getName():返回字段名称
/**
     * Returns the name of the field represented by this {@code Field} object.
     */
    public String getName() {
        return name;
    }
  • getType():返回字段类型,也是一个Class实例,eg:String.class
/**
     * Returns a {@code Class} object that identifies the
     * declared type for the field represented by this
     * {@code Field} object.
     *
     * @return a {@code Class} object identifying the declared
     * type of the field represented by this object
     */
    public Class<?> getType() {
        return type;
    }
  • getModifiers():返回字段的修饰符,它是一个int值,不同的bit表示不同的含义。
Field f = Student.class.getDeclaredField("score");
f.getName();//"score"
f.getType();//int
int m = f.getModifiers();
Modifier.isFinal(m);
Modifier.isPublic(m);
Modifier.isProtected(m);
Modifier.isPirvate(m);
Modifier.isStatic(m);
获取字段值

利用反射拿到字段的Field实例只是第一步,我们还可以拿到一个实例对应的该字段的值:

public class ReflectField{
	public static void main(String[] args){
		Student student = new Student("张三")
		Class cls = student.getClass();
		Field f = cls.getField("name");
		//f.setAccessible(true);
		Object value = f.get(student)zhu;
		//f.set(student,"李四");//修改反射字段的值
		System.out.println(value);//张山
	}
}

注意: 如果访问的字段被定义为一个private的字段,直接访问时会出现IllegalAccessException,所以当访问一个被修饰为private的字段时,先在之前写一句

field.setAccessible(true);//一律允许访问

通过Field实例可以读取或设置某个对象的字段,如果存在访问限制,要首先调用setAccessible(true)来访问非public字段(如果JVM运行期存在SecurityManager,那么它会根据规则进行检查,有可能阻止setAccessible(true),例如,某个SecurityManager可能不允许对Java核心库的类调用该方法,这样可以保证JVM核心库的安全)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值