Java中的反射(3)——在运行时使用反射分析实例化的对象

时间:2021-09-27 09:21:29

在上一篇我们学习了利用反射去分析一个类的能力,在这一篇我们将继续讲解利用反射去分析运行时的对象。

我们都知道对象是类的实例化,因此在创建一个对象的时候我们一般都会为这个对象所属类的相应字段设置相应的值,如上一篇创建的Persion类,当我们想实例化一个Persion对象的时候都会这样做:

Persion persion=new Persion(18,"张锡凯");
//这里我们就为这个类的age字段和name字段赋予了18和"张锡凯两个值

我们在这里就是要分析这个persion对象的age和name的实际值,方法如下:

Class cl=persion.getClass();
Filed f=cl.getDeclaredFiled("name");//根据类的字段名获取一个Filed对象
Object v=f.get(persion);//调用Filed对象的get()方法(参数为一个类的某一个实例对象),返回结果为这个对象的相应字段的实例值

步骤:

  • 1.根据一个对象获取一个Class对象
  • 2.根据Class对象调用getDeclaredFiled(String name)(参数为类的字段名)获取一个Filed对象
  • 3.调用Filed对象的get(对象实例)方法(参数为一个类的某一个实例对象)

    注意:步骤一和步骤三中的所提到的对象要为同一个对象。

写到这里似乎一切都没有问题,但在实际测试中f.get(persion)方法会抛出一个IllagalAccessException异常。原因在于:除非拥有访问权限,否则Java安全机制之允许查看任意对象有哪些域但不许读取它们的值。

对于Filed Method 和Constructor都有类似的安全机制,同时他们都有一个setAccessible方法,即授予访问权限。

Class cl=persion.getClass();
Filed f=cl.getDeclaredFiled("name");
f.setAccessible(true);//授予访问权限
Object v=f.get(persion);

再运行这段代码便不会报错了。在这里补充一点,setAccessible方法是AccessibleObject类的一个方法,Filed Method 和Constructor都继承了AccessibleObject。

Filed有get方法,同样也有set方法,我们可以通过这个方法来改变一个对象的相应字段的值,例如将上面实例persion的姓名改成张星宇

f.set(perion,"张星宇");//将persion对象的f域的值设置成“张星宇”