反射从0到入门 (4)

运行结果:

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 实例既能获取指定实例的字段值,也可以设置字段的值。

设置字段值通过 Fieldset 方法实现。

// 第一个参数是指定的实例
// 第二个参数是待修改的值
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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfwdg.html