一、反射的概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。java中都有对应的类,比如:成员变量类Field、方法类Method、构造方法Constructor等等。
二、Class类的api
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(相同类的多个实例共用一个Class对象,包括基本数据类型)
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。
没有公共的构造方法,方法共有64个太多了。下面用到哪个就详解哪个吧
三、反射的使用
先写一个Student类,用于测试使用。
1、获取Class对象的三种方式
1.1 Object ——> getClass();
1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性;
1.3 通过Class类的静态方法:forName(String className)(常用)。
//获取Class
public static void main(String[] args) throws Exception{
//第一种方式
Student stu = new Student();
Class cla1 = stu.getClass();
System.out.println(cla1.getName());
//第二种方式
Class cla2 = Student.class;
System.out.println(cla1 == cla2);
//第三种方式
Class cla3 = Class.forName("day01.Student");
System.out.println(cla2 == cla3);
}
注意:在运行期间,一个类,只有一个Class对象产生。
三种方式常用第三种,第一种对象都有了还要反射干什么。
第二种需要导入类的包,依赖太强,不导包就抛编译错误。
一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法。
2.通过反射获取方法,属性,构造函数等。
获取这些基本上都是一个套路,知道一个其它的就都一样了。
//获取全部公共构造函数
Constructor[] conArray = cla3.getConstructors();
for (Constructor constructor : conArray) {
System.out.println(constructor);
}
//获取全部构造函数(包含:私有、受保护、默认、公有)
Constructor[] conArray1 = cla3.getDeclaredConstructors();
for (Constructor constructor : conArray) {
System.out.println(constructor);
}
//获取特定公共构造函数
Constructor con1 = cla3.getConstructor(int.class,String.class,String.class);
System.out.println(con1);
//获取特定构造函数(包含:私有、受保护、默认、公有)
Constructor con = cla3.getDeclaredConstructor();
System.out.println(con);
con.setAccessible(true);//暴力访问(忽略掉访问修饰符)
//调用构造函数,即实例化
Object obj1 = con.newInstance();