1.java反射基础
2.java反射进阶
反射的两个显著的作用
- 反编译: .class —> .java
- 通过反射机制访问java对象中的属性、方法、构造方法等。
反射机制需要使用到的类
- java.lang.Class ————类的创建
- java.lang.reflect.Constructor————反射类中的构造方法
- java.lang.reflect.Field————反射属性
- java.lang.reflect.Method————反射方法
- java.lang.reflect.Modifier————访问修饰符的信息
实现反射,实际上是得到Class对象,使用java.lang.Class这个类。这是Java反射机制的起源,当一个类被加载后,Java虚拟机会自动产生一个Class对象。
1.三种获取Class对象的方式
(1).反射机制获取类,以简单获取Reflect类为例
Class c1=Class.forName("com.zhangqing.Reflect")
(2).java中每个类都有Class属性
Class c2=Reflect.Class;
(3).通过getClass方法获取
Class c3=new Reflect().getClass();
这三种初始化方式的区别在于:
- 第一种Class.forName方式,会让ClassLoader装载类,并执行类的初始化。
- 第二种getClass()方式,返回类对象运行时真正所指的对象、所属类型的Class对象。
- 第三种Reflect.class方式,ClassLoader装入内存,不对类进行类的初始化操作。。
2.无参数创建对象
(1). forName 中的参数需要填入全路径名
Class c=Class.forName("com.zhangqing.Reflect");
Object o=c.newInstance();
New和newInstance()的区别
- New是直接创建一个实例,同时完成类的装载和连接。
- newInstance()是使用类的加载机制,创建了一个实例。这个类已经被加
载,并且已经被连接,这是因为forName会让ClassLoader装载类和进行类的初始化工作,其实际创建的是Object对象. - 使用类加载机制可以很灵活地创建类的实例,当更换类的时候,无须修改以前的代码。
- New是一个关键字,可以传入参数取决于对象的构造方法,而newInstance是一个方法,只能传入无参数构造。
3.有参数创建对象
有参构造方法在调用参数时需要药天蝎的参数类型:
Constructor<?> csr=c.getConstructor(String.class,int.class);
Object o=csr.newInstance("zhangqing",26);
这里的getConstructor方法会返回一个Constructor对象,它反反映类此Class对象所表示的类指定的公共构造方法。
4.反射类中的属性需要使用Field对象
Field field=cls.getDeclaredField("name");
使用setAccessible取消封装,特别是可以取消私有字段的访问限制。
field.setAccessible(true);
O是属性所在的类对象(类的实例)
field.set(0,"zhangqing");
- Field类描述的是属性对象,其中可以获取到很多属性的信息,包括名字、属性类型、属性的注解。
- 在安全管理器中会使用checkPermission方法来检查权限,而setAccessible(true)并不是将方法的权限改为public,而是取消Java的权限控制检查,所以即使是public方法,其accessible属性默认也是false.
5.修改属性中修饰符
Field field=cls.getDeclaredField("name");
String priv=Modifier.toString(file.getModifiers());
- getModifiers()返回的是一个int类型的返回值,代表类、成员变量、方法的修饰符。
6.反射类中的方法
(1).获取类中的方法
Method m=c.getDeclaredMethod("setName",String.class);
(2).通过反射调用方法
m.invoke(c,"zhangqing");
- getDeclaredMethod()获取的是类自身声明的所有方法,包含public,protected和private方法。
- Method中的invoke方法用于检查AccessibleObject的override属性是否为true.
- AccessiobleObject是Method、Field、Constructor的父类,override属性默认为false,可调用setAccessible方法改变,如果设置为true,则表示可以忽略访问权限的限制,直接调用。