运行结果:
Exception in thread "main" java.lang.IllegalAccessException: Class com.javastudy.reflection.Fields.FieldTest4 can not access a member of class com.javastudy.reflection.Fields.Animal with modifiers "private"WTF?竟然出现异常了,小李你是在玩我么,第一次就可以,第二次又提示没有权限,到底能不能获取我想要的值。当然能,不能我就秃给你看。
我们只需要在 filed.get() 的上一步加上下面的代码就可以了。管你是 public 还是 private.
field.setAccessible(true);那我们想一想为什么第一次不加上面的代码也能访问呢?
因为是在自己的类里访问的,就拿你自己想一想,你有一个鼻子和两个耳朵,它们就是你私有的(private),你可以随便摸他们和抠他们(呕),但是别人想碰的时候,必须要经过你的同意才行(setAccessible(true))。这么理解下刚才的代码,你就明白了。如果还不明白可以打开上面的两段注释:
Animal animal = new Animal();animal.testFiled();
运行结果:
不是秃头的小李程序员222设置字段值
通过 Field 实例既能获取指定实例的字段值,也可以设置字段的值。
设置字段值通过 Field 的 set 方法实现。
// 第一个参数是指定的实例// 第二个参数是待修改的值
void set(Object obj, Object value)
示例代码如下:
public class FieldTest5 {public static void main(String[] args) throws Exception {
Teacher teacher = new Teacher("不是秃头的小李程序员");
Class c = teacher.getClass();
Field field = c.getDeclaredField("name");
field.setAccessible(true);
field.set(teacher,"小李不秃头");
System.out.println(field.get(teacher));
}
}
class Teacher{
private String name;
public Teacher(String name){
this.name = name;
}
public String getName() {
return name;
}
}
打印结果:
小李不秃头为了不秃头,我容易么(此处嘤嘤嘤)。嘤完就该提问题了
Field 在 get 和 set 的 obj 参数有什么作用?
回答:我们可以通过查看 api 的注释,了解到这两个方法在获取静态实例的时候,obj 可以传 null,如果要获取对象的实例 obj 参数就不能为空,否则会返回 NullException。
小结Java 的反射 API 提供的 Field 类封装了字段的所有信息:
通过 Class 实例获取 Field 实例的方法:getField(String name),getFields(),getDeclaredField(),getDeclaredFields()
通过 Field 实例获取字段信息的方法:getName(),getType(),getModifiers()
通过 Field 实例可以读取或者设置某个对象的字段,如果存在访问限制,首先要调用 setAccessible(true),再访问非 public 字段。
Method 获取 Method通过 Class 实例获取所有 Method 的信息,Class 类提供了以下几个方法来获取方法:
Method getMethod(String name, Class… parameterTypes):根据方法名和参数类型获取某个 public 的 Method
Method[] getMethods():获取所有 public 的 Method
Method getDeclaredMethod(String name, Class… parameterTypes):根据方法名和参数获取当前类的某个 Method
Method[] getDeclaredMethods():获取当前类的所有 Method