欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

反射学习笔记

程序员文章站 2022-03-16 08:46:43
...

1.java的反射机制:

JAVA反射机制是在运行状态中,
对于任意一个实体类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意方法和属性;
这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制
**

2、反射机制的实现实质:Class

api中描述Class类:
Class类的实例表示正在运行的 Java 应用程序中的类和接口
(理解:所有的类和接口都是是Class类的实例)在加载.class文件时会根据.class文件在堆中创建一个Class类的对象 与 该类或接口 相映射
枚举是一种类,注释是一种接口。(理解:枚举和注释也是一个Class对象)
每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

因为每个类都是一个Class对象,想操作类,就要先获取类,所以要获取与其映射的Class对象

1.获取类的Class对象

1、根据对象,对象名.getClass();
2、根据类名,类名.class
3、根据Class工具类的静态方法,Class.forName("全类名")
注意:类的完全限定名/类的全名 指src下开始的包的路径。forName()方法需要抛异常,找不到类异常,ClassNotFountException
Class的泛型加上后,newInstance()时不用手动强转。
举例:

//1
Student s = new Student();
Class<? extends Student> clazz = s.getClass();
//2
Class<?> clazz = Student.class;
//3
Class<?> clazz = Class.forName("com.reflect.test.Student");

2.暴力反射

1.通过Class对象中的getDeclaredXxx()方法获取类中所有的成员(属性,方法,内部类)
2.修改对该成员的访问权限
成员变量,构造方法,成员方法都是AccessibleObject类型的子类,具有判断是否可以访问 和 设置是否可以访问的方法。
isAccessible():判断当前对象是否可以被访问
setAccessible(boolean flag):true,设定当前对象可以被访问。false相反。
setAccessible(true)后,私有成员也可以被访问和修改

3.根据Class对象创建实例(获取构造方法)

根据指定类的Class对象创建一个该类的新的对象
方法1:根据Class对象直接newInstance();调用该类无参构造方法创建一个新的对象。
注意:clazz的newInstance()要求必须有一个无参构造方法,且返回值是Object

Class<?> clazz = Class.forName("com.reflect.test.Student");
Student stu = (Student)clazz.newInstance();

方法2:获取构造方法,用指定构造方法创建对象。
注意:
getConstructors();//获取student的所有public修饰的构造方法
getDeclaredConstructors();//获取全部构造方法,包括private
getConstructor(String.class , int.class);//根据指定的参数获取构造方法,参数必须也是参数类型对应的Class对象
getDeclaredConstructor(String.class,int.class);//根据参数获得构造方法(所有修饰符都可以)

Class clzz = Student.class;
//获取构造方法
Constructor[] cons = clzz.getConstructors(); 获取student的所有public修饰的构造方法
Constructor[] cons1 = clzz.getDeclaredConstructors(); 获取全部构造方法,包括private
Constructor<?> con1 = s1.getConstructor(String.class,int.class); 根据指定的参数获取构造方法(只有public修饰的)
Constructor<?> con2 = s1.getDeclaredConstructor(String.class, int.class , int.class); 根据参数获得任何修饰符修饰的构造方法(包括private//根据构造方法创建对象
1.如果是public修饰的构造方法(有权限调用,直接调用)
Student stu1 = (Student) con1.newInstance("张三",14);//有参数直接加参数就可以
2.如果是private修饰的构造方法(没权限调用,暴力反射)
con2.setAccessible(true);//设置为允许访问
Student stu2 = (Student) con2.newInstance("张三",14,15);

4.根据Class对象获取属性

5.根据Class对象获取方法