java基础反射知识总结

反射是什么?

在运行状态中,获取一个类的所有属性和方法。这种动态获取信息以及调用对象的方法的功能。

使用反射机制的一些框架?

Retrofit中的注解功能、EventBus,动态生成框架 Gson。

使用反射技术查看类信息

获取Class对象的三种方法

使用Object.getClass方法

如果我们能知道一个对象,可以通过调用这个对象的getClass方法获得一个Class对象。
例如:

Person person = new Person();
Class<? extends Person> aClass = person.getClass();
System.out.println(aClass.getName());

这时候就会打印这个对象的全包名,aClass中还有其他信息。

使用.class方法
Class<? extends Person> aClass = Person.class;
System.out.println(aClass.getName());
System.out.println(int.class);

如果没有获取某个类的对象,无法使用getClass方法,可以直接在类名加上.class来获取,这种方式可以用于基本数据类型。

使用Class.forName()方法

这个方法要使用一个类的完整路径,就可以使用Class.forName(“类的完整路径”)来得到相应的Class。

 try {
        Class mclass1 = Class.forName("main.fanshe.Person");
        System.out.println(mclass1.getName());
     } catch (ClassNotFoundException e) {
            e.printStackTrace();
     }

注意:使用Class的newInstance()方法来创建对应类的实例,需要有默认的构造器,执行newInstance()方法实际上市利用默认构造器来创建该类的实例。

Class mclass1 = Class.forName("main.fanshe.Person");
Object o = mclass1.newInstance();

通过反射获取成员变量

常用获取成员属性的方法


Field[] declaredFields = mclass1.getDeclaredFields();//获取Class对象的所有属性

Field[] fields = mclass1.getFields();//获取class对象的public属性

Field ageField = mclass1.getDeclaredField("age");//获取class指定属性

Field desFiedl = mclass1.getField("name");//获取class指定的public属性


如果获取到属性可以用过set方法进行修改例如:

 Field ageField = mclass1.getDeclaredField("age");//获取class指定属性
 ageField.setInt(o,22);

如果这个属性是用private修饰的话,这样写的话代码会报错

java.lang.IllegalAccessException: Class main.fanshe.Main can not access a member of class main.fanshe.Person with modifiers "private"
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
    at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
    at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
    at java.lang.reflect.Field.setInt(Field.java:946)
    at main.fanshe.Main.main(Main.java:50)

这时我们要添加 ageField.setAccessible(true);这个方法来声明这个变量是可以访问的就没问题了,但是使用这个方法也可能会导致些其他问题,例如
在运行时虽然你通过反射修改了变量 a 的值,但其他部分可能还在使用原来的值。

通过反射获取成员方法

Method[] methods = mclass1.getDeclaredMethods();//获取class对象的所有声明方法
Method[] allMethods = mclass1.getMethods();//获取class对象的所有public声明方法
Method method = mclass1.getMethod("getAge");//根据方法名返回方法
Method method2 = mclass1.getMethod("getAge",String.class);//根据带指定形参列表的public方法
System.out.println(method.toString());

可以通过method.invoke(o);这个方法调用反射到的方法。

总结

反射还有好多其他方法,可以通过查询API获知,例如获取构造方法等,功能貌似还是比较强大的,但是反射的一些操作可能会引起性能消耗,例如修改某个成员变量的时候,需要引发验证访问权限等额外操作等。所以使用反射的时候也许要考虑下性能方面的问题。

本篇文章参考:http://blog.csdn.net/u011240877/article/details/54604212

    原文作者:开飞机的老舒克
    原文地址: https://www.jianshu.com/p/b2e0c3d1a0ce
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞