Java反射机制概述
Java反射(Reflection)允许应用程序在运行时借助于反射API,来获取所有类或接口的内部信息,并且能直接操作任意对象的内部属性及方法。反射机制的核心类为java.lang.Class。
类加载完后,会在堆内存的方法区中产生一个Class类型的对象。
Class类没有公开的构造函数,是由类加载器的defineClass方法构造而成。所以Class对象不是“new”出来的,而是通过方法来获取的。
这个Class对象具有类的完整结构信息,并且一个类只有一个Class对象。
什么是反射?
反射机制的核心就是获取任意一个类的属性和方法,还可以操作类或者对象的属性和方法
优点:让java代码更加灵活,为各种框架提供开箱即用的功能
缺点:对安全和性能有一定的影响
反射的应用场景?
spring boot、mybatis等框架中以及动态代理的实现
Java中使用的注解
使用反射机制来编写中间件
使用反射机制来自定义注解,以此来优化代码和解耦代码逻辑
获取Class对象
获取Class对象有以下四种方式:
通过类对象获取;
通过类直接调用class获取;
通过Class.forName获取;
通过类加载器获取。
下面使用代码展示获取 Person 类的Class对象的四种方式:
@Test
public void testClassFor() {
// 1.通过类实例获取
Person person = new Person();
Class<? extends Person> clazz1 = person.getClass();
System.out.println("01 - " + clazz1);
// 2.通过类直接调用class获取
Class<Person> clazz2 = Person.class;
System.out.println("02 - " + clazz2);
// 3.通过Class.forName获取
Class<?> clazz3 = null;
try {
clazz3 = Class.forName("io.github.gozhuyinglong.reflection.Person");
} catch (ClassNotFoundException e) {
// 当找不到指定类时,会抛出此异常
e.printStackTrace();
}
System.out.println("03 - " + clazz3);
// 4.通过类加载器获取
ClassLoader classLoader = this.getClass().getClassLoader();
Class<?> clazz4 = null;
try {
clazz4 = classLoader.loadClass("io.github.gozhuyinglong.reflection.Person");
} catch (ClassNotFoundException e) {
// 当找不到指定类时,会抛出此异常
e.printStackTrace();
}
System.out.println("04 - " + clazz4);
// hashCode相等,说明这四种方式获取的是同一个实例
System.out.println("05 - " + clazz1.hashCode());
System.out.println("06 - " + clazz2.hashCode());
System.out.println("07 - " + clazz3.hashCode());
System.out.println("08 - " + clazz4.hashCode());
}
输出结果:
01 - class io.github.gozhuyinglong.reflection.Person
02 - class io.github.gozhuyinglong.reflection.Person
03 - class io.github.gozhuyinglong.reflection.Person
04 - class io.github.gozhuyinglong.reflection.Person
05 - 721748895
06 - 721748895
07 - 721748895
08 - 721748895
通过上面的输出结果可以看出,这四个Class对象的hashCode相同,说明使用这四种方式获取的是同一个对象。
反射机制中常用类?
Java.lang.reflect
Java.lang.Class