1. 反射快速入门
re.properties
classfullpath=com.sls.Cat
methodName=hi
Cat类
public class Cat {
private String name;
public void hi(){
System.out.println("hello");
}
}
反射测试类
public class demo01 {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Properties properties = new Properties();
properties.load(new FileInputStream("src/main/java/re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String methodName = properties.get("methodName").toString();
System.out.println(classfullpath);
// 1. 加载类,返回Class类型的对象cls
Class<?> aClass = Class.forName(classfullpath);
// 2. 通过aclss得到你要加载的类com.sls.Cat的对象实例
Object o = aClass.newInstance();
// 3. 通过aclss得到你要加载的类com.sls.Cat的methodName的方法实例对象
// 也就是在反射中可以把方法视为对象
Method method = aClass.getMethod(methodName);
// 4. 调用方法 方法.invoke(对象)
method.invoke(o);
}
}
2. 反射机制原理
反射机制运行程序在执行期间借助于 Refleciton API获得类的内部信息
- 成员变量
- 构造器
- 成员方法
并能操作对象的属性以及方法
加载完类之后,在堆中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象包含了类的完整结构信息,通过这个对象得到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以形象的称为:反射
3. 反射相关类
3.1 反射机制的功能
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时得到任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的成员变量和方法
- 生成动态代理
3.2 主要类
- java.lang.Class:代表一个类 Class对象表示某个类加载后在堆中的对象
- java.lang.reflect.Method 代表类的方法
- java.lang.reflect.Field 代表类的成员变量
- java.lang.reflect.Constructor 代表类的构造方法
Field ageField = aClass.getField("age");
System.out.println(ageField.get(o));
Constructor<?> constructor = aClass.getConstructor();
System.out.println(constructor);
Constructor<?> constructor1 = aClass.getConstructor(int.class);
System.out.println(constructor1);
3.3 优缺点
优点:
可以动态的创建和使用对象,使用灵活,没有反射机制,框架技术就失去了底层支撑
缺点:
使用反射基本是解释执行,对执行速度有影响
3.4 反射调用优化
Method和Field,Constructor对象都有setAccessible()方法。作用是启动和关闭访问安全检查的开关
参数为true:取消安全检查
参数为false:开启安全检查
4. Class类
4.1 基本介绍
- Class类也是类,继承了Object类
- Class类对象不是new出来的,而是系统创建的(类加载系统加载的)
- 对于某个类的Class类对象,在内存中只有一份,所以系统只加载一次
- 每个类的实例都会记得自己是由那个Class实例所生成的
- 通过Class对象可以完整的得到一个类的完整结构
- Class对象是存放在堆中
- 类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据
4.2 Class类的常用方法
4.3 获取Class类对象的方式
- Class.forName() 多用于配置文件,读取类全路径,加载类
- 类.class 多用于参数传递,比如通过反射得到对应构造器
cls.getConstructor(String.class)
-
对象.getClass() 通过创建好的对象
-
类加载器得到Class对象
5. 类加载
5.1 基本概念
静态加载:编译时加载相关类,如果没有则报错,依赖性太强
动态加载:运行时加载相关类,如果运行时不用该类,则不报错
5.2 类加载时机
类加载时机
- 当创建对象时(new) /静态加载
- 当子类被加载时,父类也加载 /静态加载
- 调用类中的静态成员 /静态加载
- 通过反射 /动态加载
5.3 类加载各阶段完成的任务
6. 通过反射获取类的结构信息
6.1 Class类
6.2 Field类
6.3 Method类
6.4 Constructor类
7. 通过反射创建对象
8. 通过反射访问类中的成员