反射
定义
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
forName()
Class cls = Class.forName(路径);
Object o = cls.newInstance();
o.getClass();//运行类型
getMethod()
Method mt = cls.getMethod(方法名);
mt = invoke(o);
getField()
Field nameField = cls.getField("变量名");
//getField不能得到私有的属性
nameField.get(o);
Field[] fields = clazz.getDeclaredFields();
//获取所有属性
String name = field.getName();
//获取属性名
getConstructor()
Constructor con = cls.getConstructor();
Constructor con2 = cls.getConstructor(String.class);
//String.class就是String类的Class对象
原理
作用
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时得到任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的成员变量和方法
- 生成动态代理
反射相关的主要类
java.lang.Class
代表一个类,Class对象表示某个类加载后在堆中的对象
java.lang.reflect.Method
代表类的方法,Method对象表示某个类的方法
java.lang.reflect.Field
代表类的成员变量,Field对象表示某个类的成员变量
java.lang.reflect.Constructor
代表类的构造方法,Constructor对象表示某个类的构造器
这些类在java.lang.reflect里看
反射调用优化
关闭访问检查
- Method和Field,Constructor对象都有setAccessible()方法
- setAccessible()作用是启动和禁用访问安全检查的开关
- 参数值为true表示反射的对象在使用时取消访问检查,提高反射的效率,参数值为false表示反射的对象执行访问检查
field.setAccessible(true);
//这样可以访问私有属性
获取Class类对象
-
前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能抛出ClassNotFoundException,实例:
Class cls1 = Class.forName("java.lang.Cat");
应用场景:多用于配置文件,读取类全路径,加载类
-
前提:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能最高,实例:
Class cls2 = Cat.class;
应用场景:多用于参数传递,比如通过反射得到对应构造器对象
-
前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象,实例:
Class clazz = 对象.getClass(); //运行类型 //应用场景:通过创建好的对象,获取Class对象
-
其他方式
ClassLoader cl = 对象.getClass().getClassLoader(); Class clazz4 = cl.loadClass("类的全类名");
-
基本数据类型(int,char,boolean,float,double,byte,long,short)按如下方式得到Class类对象
Class cls = 基本数据类型.class
-
基本数据类型对应的包装类,可以通过.type得到Class类对象
Class cls = 包装类.TYPE
哪些类型有Class对象
- 外部类,成员内部类,静态内部类,局部内部类,匿名内部类
- interface:接口
- 数组
- enum:枚举
- annotation:注解
- 基本数据类型
- void