含义
反射是指在项目运行过程中,对于任意一个类可以获取其属性和方法信息,对于任意一个对象都可以调用其所有属性和方法,这种动态获取类信息以及动态调用对象方法的能力称为反射
作用
- 获取类名、package信息、所有属性、方法、注解、类型、类加载器等
- 判断对象所属的类
- 获取/修改对象中的属性值
- 调用对象中的方法
怎么使用反射
通过反射获取对象
- 获取Class对象
Class class = Class.forName("com.calss.path")
- 创建对象
1 使用Class 对象的 newInstance() 方法
Object object = (Object)class.newInstance()
2 通过 Constructor 对象的 newInstance() 方法
Constructor constructor = class.getConstructor();
Object obj= (Object)constructor.newInstance();
获取类的成员变量的信息
Field[] fields = cls.getDeclaredFields();
方法名 | 用途 |
---|---|
getField(String name) | 获取某个public属性 |
getFields() | 获取所有public属性 |
getDeclaredField(String name) | 获取某个属性(public或非public) |
getDeclaredFields() | 获取所有属性(public或非public) |
获取类的方法
Method[] methods = cls.getDeclaredMethods();
方法名 | 用途 |
---|---|
getMethod(String name, Class<?>… parameterTypes) | 获取该类某个public方法 |
getMethods() | 获取所有的public方法 |
getDeclaredMethod(String name, Class<?>… parameterTypes) | 获取该类某个方法(public或非public) |
getDeclaredMethods() | 获取所有方法(public或非public) |
获得构造函数
Constructor[] constructors = cls.getDeclaredConstructors()
方法名 | 用途 |
---|---|
getConstructor(Class<?>… parameterTypes) | 获取该类某个共有构造方法 |
getConstructors() | 获取所有的构造方法 |
getDeclaredConstructor(Class<?>… parameterTypes) | 获取该类构造方法(public或非public) |
getDeclaredConstructors() | 获取所有构造方法(public或非public) |
反射原理
在编译过程中.java文件会被编译成字节码.class文件,在项目运行中类被首次使用时将类信息、方法信息、字节码信息加载入JVM方法区中,并产生一个Class对象,之后会通过该Class对象在JVM中创建类实例。
反射原理即为:通过类名获取对应的Class对象,若该类为首次使用,则需要先将该类相关信息加载入方法区中,否则直接使用方法区中的类信息创建Class对象,通过Class对象完成实例对象的创建
类加载
Java中类加载有Class.forName(“class.path”)和Classloader.loadClass(“class.path”)两种方式
- Class.forName:底层实际也是调用了classLoader.loadClass方法,不同之处在于会执行类中的静态代码块,及静态属性的赋值操作等类初始化操作
例如JDBC使用Class.forName()方法来加载数据库连接驱动,原因是在Driver.class中是使用静态代码块的方式,将驱动纳入驱动管理器DriverManager管理
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
public Driver() throws SQLException {
}
static {
try {
DriverManager.registerDriver(new Driver());
} catch (SQLException var1) {
throw new RuntimeException("Can't register driver!");
}
}
}
- Classloader.loadClass:不会执行类中的静态代码块,及静态属性的赋值操作