Java反射知识总结(2)——阅读

原创
2016/01/20 10:09
阅读数 120

       上一部分介绍了反射的一些基本内容,现在将利用反射完成更多的事情。

一、  Field类

      Field类封装了属性的信息,一个Field类封装了一个属性的信息,类似于Method对象封装了方法的信息一样。那么如何获取Field对象呢?在Class类中通常有以下两个方法:

     1、Field  getDeclaredField(String name)                                    ----方法1

     2、Field  getField(String name)                                                  -----方法2

   是不是和获取Method对象的方法很相似呢?不错,获取Field基本和获取Method对象是一致的。

    getField 方法可以获 得本类的公开属性以及从父继承到,但是无法获非公开属性;而getDeclaredField方法只能获得本类属性,但这包括的本类的非公开属性。

   例如:要获取Student类的name属性的Field对象,可以使用如下的代码:

     Class c=Student.class;

     Field nameField=c.getField("name");

   这样就获取到了对应的Field对象。

 

  那么获取到Field对象之后,我们可以修改相关属性的值,那优势如何操作的呢?

  利用public void set(Object obj,Object value)方法来修改属性

  例如:

        Student u =new Student();

       Filed ageField=u.getClass().getDeclaredField("age");

       ageField.setAccessible(true);

       ageField.set(u,new Integer(18));

    需要注意的是,这里我们使用了getDeclaredField方法,因为此处的age是作为一个私有的属性的,而getField只能访问公开的属性,而对于私有的属性一般情况下是无法读取、修改的,而通过反射确可以修改,只需要增加 

      ageField.setAccessible(true)

        代码即可。

二、利用反射调用对象的方法

    利用反射调用方法,首先我们需要获取到被调用的方法所对应的Method对象,然后利用Method对象调用invoke方法。invoke方法签名如下:

    public Object invoke(Object obj,Object[] args)

    在这个方法中有两个参数,参数1 obj表示对那个对象调用方法,参数2 args表示调用方法时候的参数列表,invoke方法返回值对应于Method对象所代表的方法调用时候的返回值。

   例如:

         Student stu=new Student();

        Method m=stu.getClass().getDeclaredMethod("study",new Class[]{int.class,double.class});

        Object result=m.invoke(stu,new Object[]{new Integer(10),new Double(1.5)});

      上面就是利用反射调用方法。与Field对象类似,也可以调用一个类的私有方法,只需要在调用Method方法之前,先调用setAccessible(true)即可。


 反射的优势:

      其实总结来说,反射的优势在于更多的复用代码,这也是为什么工具和框架编写时候常用反射的原因,下面一个例子大致可以窥见端倪

      原:

          Student s =new Student();

          s.study();

    反射:

       String className = "Student";

       Class c = Class.forName(className);

       Object o = c.newInstance(); 

       String methodName = "study"; 

       Method m = c.getMethod(methodName , new Class[]{}); 

        m.invoke(o , new Object[]{}); 

  

当然,这里并不是鼓励大家滥用反射。反射技术有着非常显著的几个缺点。

  1. 运行效率与不用反射的代码相比会有明显下降。

   2. 代码的复杂度大幅提升,这个从量上家就能比较出来

  3. 代码会变得脆弱,不易调试。使用反射我们就在一定程度上绕开了编译器的语法代码会变得脆弱,不易调试。 使用反射我们就在一定程度上绕开了编译器的语法检查,例如用反射去调一个对象的方法而该对象没有这个方法那么在编译时,编译器是无法发现的,只能到运行时由 JVM 抛出异常。

 



展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
3 收藏
1
分享
返回顶部
顶部