一、概述
反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。
二、Class类
1、类也是对象
java中一切皆对象,类也是对象,是Class类的实例对象。Class是类的类类型。基本类型(包括void)也有类类型。
2、表示方式
- 类的静态成员变量:类.class
- 类的实例对象getClass方法:c.getClass()
- Class.forName("com.xin.demo.Test")
三种方式得到的class都是相同的,因为一个类只可能是Class类的一个实例对象。
3、class创建类的实例对象
c.newInstance(),需要类有无参的构造方法。
三、动态加载类
1、什么是动态加载类
编译时刻加载类是静态加载,运行时刻加载类是动态加载。静态加载类时若没有类不能通过编译,动态加载可以通过编译
2、加载类方式
- 动态加载:Class.forName(),newInstance()
- 静态加载:new创建对象
3、动态加载类的优点
增加新功能时不需修改原文件,能通过配置动态加载新功能,功能型类一般使用动态加载。
四、反射
1、成员方法
- Method类封装了成员方法的信息
- Class.getMethods():得到所有的public方法,包括父类继承的
- Class.getDeclaredMethods():得到本类声明的所有方法,不问访问权限
- Method.getReturnType():得到方法的返回值类型的类类型
- Method.getParameterTypes():得到方法参数类表的类类型
- Method.getName():得到方法的名字
2、成员变量
- Field类封装了成员变量的信息
- Class.getFields():得到所有的public成员变量,包括父类继承的
- Class.getDeclaredFields():得到本类声明的所有成员变量,不问访问权限
- Field.getType():得到成员变量类型的类类型
- Field.getName():得到成员变量的名字
3、构造方法
- Constructor类封装了构造方法的信息
- Class.getConstructors():得到所有的public构造方法,包括父类继承的
- Class.getDeclaredConstructors():得到本类声明的所有构造方法,不问访问权限,建议使用此方法
- Constructor.getParameterTypes():得到构造参数的类类型
4、成员方法反射
method.invoke(对象,参数类别)
//1、获取方法
//Method m = c.getMethod("print", new Class[]{int.class,int.class});
Method m = c.getMethod("print", int.class,int.class);
//2、执行方法
//Object o = m.invoke(a1,new Object[]{10,20});
Object o = m.invoke(a1, 10,20);
// Method m2 = c.getMethod("print", new Class[]{});
Method m2 = c.getMethod("print");
// m2.invoke(a1, new Object[]{});
m2.invoke(a1);
5、泛型的本质
泛型的本质是防止错误输入的,只在编译阶段有效。编译后就没有泛型存在,通过反射可以绕过编译。