java之反射访问私有属性


对于任意一个object实例,只要我们获取了它的class,就能得到它的一切信息。

Class类听过了几个方法获取字段:

Field getField(name):根据字段名获取某个public的field(包括父类的public 字段)

Filed getDeckaredField(name):根据字段名获取当前类的某个field(不包括父类)

Field[] getFields():获取所有的public 的field(包括父类)

Filed[] getDeclaredFields():获取当前类的所有field(不包括父类)

获取字段的值:

先获取Class实例,在获取Field实例,再用Field.get(Object)获取指定实例的指定字段的值:

package reflaction;

import java.lang.reflect.Field;

public class demo1 {

public static void main(String[] argsl) throws Exception {
Class stdClass = Student.class;
System.out.println(stdClass.getField("score"));
//System.out.println(stdClass.getField("name"));
System.out.println(stdClass.getDeclaredField("grade"));

Object p = new Person1("xiao ming");
Class c = p.getClass();
Field f = c.getDeclaredField("name");
f.setAccessible(true);
Object value = f.get(p);
System.out.println(value);
}
}

class Person1 {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Person1() {
}

public Person1(String name) {

this.name = name;
}
}

class Student extends Person1 {
public int score;
private int grade;

Student() {
super();
}

Student(String name) {
super.setName(name);
}
}

写代码过程遇到的问题就是private属性,正常情况下Main类是无法访问的,例如代码中的name属性,
这里会出现一个IllegalAccessException,解决这个问题,我们可以把name属性设置为public或者是在
调用Object value=f.get(p)之前增加一个设置
f.setAccessible(true);

这个设置的意思就是不管这个字段是不是public,一律允许访问,
setAccessible(true)有可能会失败,如果JVM运行期存在SecurityManager,这个就会根据规则进行检查,有可能会
阻止
setAccessible(true),例如某个SecurityManager可能不允许对java和javax开头的package的类调用setAccessible(true),
这样可以保证JVM核心库的安全。
问题:如果可以通过反射获取private 字段,那么类的封装还有什么意义?
正常情况下,我们是通过类的实例来访问字段的,编译器会根据public protected,private来决定是否
允许访问字段,这样就已经达到了封装的目的了,
反射是一种特殊的方式,通常反射是给工具或者底层框架来事用的,在不知道实例的任何信息的情况下,获取
特定字段的值。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM