反射的概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。
Java中为什么需要反射?
Java中编译类型有两种:
静态编译:在编译时确定类型,绑定对象即通过。
动态编译:运行时确定类型,绑定对象。动态编译最大限度地发挥了Java的灵活性,体现了多态的应用,可以减低类之间的耦合性。
Java反射语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public、static等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
Java反射(Reflection)允许应用程序在运行时借助于反射API,来获取所有类或接口的内部信息,并且能直接操作任意对象的内部属性及方法。
实现Java反射机制的类都位于java.lang.reflect包中:
Class类:代表一个类
Field类:代表类的成员变量(类的属性)
Method类:代表类的方法
Constructor类:代表类的构造方法
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
下面使用代码展示获取 类的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());
}