最近在业余时间开始重温Java基础知识,首先看的是反射相关内容,因为好多框架都用到了反射,想来理解了反射对学习框架会有很大帮助。为了更好的消化,还是做一些笔记加深一下记忆。
权且作为知识点梳理,写的不对的希望朋友们耐心指出,共同进步!
一、Class类的使用
1 一切皆对象
Java是纯面向对象语言,在Java中一切皆对象,任何一个类都是一个对象,它们都是java.lang.Class类的实例对象。
复制代码
2 获得Class类的实例对象
可通过如下三种方法获得Class类的实例对象:
* 类名.class;
* 实例对象.getClass();
* Class.forName();
复制代码
3 通过Class类创建实例
* Class类的实例对象.newInstance(),利用默认构造器创建类的实例;如:
Class clazz = DemoClass.class;
Object obj = clazz.newInstance();
* 先使用Class对象获得指定的Constructor对象,再调用Constructor对象的newInstance()方法创建对应类的实例,这种方式可以使用指定的构造器创建类的实例对象。
复制代码
4 一个类只能是Class类的一个实例
无论使用2中提到的任何一种方式获得对应类的Class实例对象,这些实例对象都是同一个:
Class clazz1 = DemoClass.class;
Class clazz2 = Class.forName("com.reflect.DemoClass");
DemoClass demo = new DemoClass();
Class clazz3 = demo.getClass();
以上clazz1、clazz2、clazz3是相等的。
复制代码
二、动态加载类
Java中类的加载分编译器加载和运行期加载,使用new关键字创建类的实例时为编译期加载及静态加载;使用Class.forName(全类名)的方式可以实现运行期加载类及动态加载。
复制代码
三、通过反射获取类中的方法
* 调用Class类的实例对象的getMethods()方法获取到类中声明的public方法包括从父类中继承来的方法,调用getMethod(方法名称,参数列表)获得指定名称、指定参数列表的方法;调用Class类的实例对象的getDeclaredMethods()获取声明的全部方法(不包括父类继承得到的),与方法的访问权限无关,同样,getDeclaredMethod(方法名称,参数列表)获得指定名称、指定参数列表的方法。
* 调用Method实例对象的getReturnType()得到返回值类型的类类型。
* 调用Method实例对象的invoke(方法所属类的实例对象,参数值)执行方法。
复制代码
四、通过反射获得类的成员变量
java.lang.reflect.Field封装了类的成员变量信息,调用Class类实例对象的getFields()方法可以获取public成员变量,调用getDeclaredFields()获取全部成员变量。
复制代码
五、反射与泛型
Java中用到泛型比较多的地方当属集合,集合中的泛型可以防止错误输入,但是只在编译器有效,编译后集合的泛型是去泛型化的。如下:
ArrayList<String> l = new ArrayList<String>();
l.add(1);//报错,编译不通过
Class clazz = l.getClass();
Method m = clazz.getMethod("add", Object.class);
m.invoke(l, 1);//未报错
复制代码
欢迎补充反射常用功能!