Java--反射
- 类加载机制
- 什么是反射
- 反射的原理
- 传统静态加载类
- 反射动态加载类
- class对象
- 三种获取class对象方式
- 类对象示例的getClass()方法
- 任何数据类型的静态class属性
- Class.forName()方法
- 两种创建对象方式
- 默认的构造器通过Class的newInstance()方法来获取
- 指定的构造器来创建
- 三种获取class对象方式
- 反射的优点和缺点
- Java反射的优点
- Java反射的缺点
- 反射的用途
类加载机制
负责读取 Java 字节代码,并转换成java.lang.Class
类的一个实例;
类加载七个步骤:加载,验证,准备,解析,初始化,使用,卸载
类加载器:启动类加载器,扩展类加载器,应用类加载器(程序员)
什么是反射
Java 反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法(本质是 JM 得到 Class 对象之后,再通过 Class 对象进行反编译,从而获取对象的各种信息)
Java 属于先编译再运行的语言,对象类型在编译期确定
当程序在运行时可能需要动态加载某些类,通过反射可以在运行时动态地创建对象并调用其属性,不需要提前在编译期确定对象类型
反射的原理
传统静态加载类
Person person = newPerson();编译时已确定对象类型,程序运行时通过类加载器加载 Person 类并创建该类的 Class 对象
反射动态加载类
Class object = Class.forName(" Person ");编译时未确定对象类型,程序运行时通过类加载器无法加载 Person 类只有到执行以上代码时,类加载器才知道对象类型,这时才开始加载Person 类,创建该类的 Class 对象,并返回给 object 变量
class对象
每个类在 JVM 中都有一个与之相关的 Class 对象,是类加载器创建的特殊对象不是类的实例化对象
Class object = Class.forName(" Person ");Person person=(Person)object.newInstance( );
反射通过获得的 Class 对象就可以得到类的元信息,调用 newInstance()方法就是通过类的元信息来动态创建 Person 对象实例
三种获取class对象方式
类对象示例的getClass()方法
Student student = new Student();
Class object = student.getClass();
任何数据类型的静态class属性
Class object = Student.class;
Class.forName()方法
Class object = Class.forName("Student");
Class<?> clazz =Class.forName("java.long.String");
两种创建对象方式
反射动态创建对象
默认的构造器通过Class的newInstance()方法来获取
指定的构造器来创建
import java.lang.reflect.Constructor;
public class ReflectDemo2 {
public static void main(String[] args) throws Exception {
/*
如何根据给定名称获取到指定的Class对象后建立该类的对象呢?
getObject_1(); 通过默认构造器new对象
getObject_2(); 通过指定构造器new对象*/
}
public static void getObject_2() throws Exception {
String className = "cn.qujianlei.domain.Person";
Class clazz = Class.forName(className);
/*
* 万一给定类中没有空参数的构造方法呢?
* 可以先获取指定的构造方法,再通过该构造方法进行实例化
*/
//1.通过Class获取指定构造方法,比如带两个参数
Constructor cons=clazz.getConstructor(String.class,int.class);//拿的是公有的
// System.out.println(cons);
//2.通过指定的构造器对象进行对象的初始化。
Object obj = cons.newInstance("lisisi",23);
}
public static void getObject_1() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//1.根据给定的类名获取Class对象
String className = "cn.qujianlei.domain.Person";
Class clazz = Class.forName(className);
Object obj = clazz.newInstance();//创建了一个Person对象,默认调用该类的空参数构造方法
//记住:一般被反射的类通常都有空参数的构造方法。
//java.lang.InstantiationException 没有调用到与之对应的构造方法
}
}
反射的优点和缺点
Java反射的优点
增加程序的灵活性,可以在程序运行过程中动态的对类进行修改和操作。
提高代码的复用率,比如动态代理,就是利用了反射来实现。
可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态调用。
Java反射的缺点
反射会涉及动态类型的解析,所以JVM无法对这些代码进行优化,导致性能要比非反射调用更低。
使用反射后,代码的可读性会下降
反射可以绕过一些限制访问属性或者方法,可能会破坏了代码本身的抽象性
反射的用途
开发各种通用框架
1.各种框架:(spring,struts....)用反射,运行时动态加载需要加载的对象。
2.各种IDE开发工具:当我们输入一个对象或类并想调用它的属性或方法时,一按点号,编译器就会自动列出它的属性或方法,这里就会用到反射。