1 反射的好处
- 在程序运行时操作对象 (就是你run了程序之后,你不能再敲代码的时候,你仍然可以通过这个反射来操作对象。比如你用的编辑器,你建个对象然后点的时候会提醒你里面有哪些方法变量什么的,这个就是程序运行时反射的应用)
- 解耦,提高程序的扩展性
- 将类的各个组成部封装为其他对象,这就是反射机制
2 Class对象
2.1 java代码执行分为三个阶段
写代码,编译成class文件–>类加载器将class文件加载进内存–>运行exe
后续运行中能使用类创建对象,就是因为上一步已经把类加载进内存了。
2.2 Class类对象构成
- Field [] 成员变量
- Constructor []构造方法
- Method [] 成员方法
3 获取Class对象的方式
- Class.forName(“全类名”) 多用于配置文件
- 类名.class 多用于出参数的传递
- 对象.getClass() 用于通过对象获取其字节码
@Test//获取Class对象的方式
public void test1() throws ClassNotFoundException {
Class cls1 = Class.forName("反射.Student");
Class cls2 = Student.class;
Student student = new Student("name", 1);
Class cls3 = student.getClass();
System.out.println(cls1);//class 反射.Student
System.out.println(cls2);//class 反射.Student
System.out.println(cls3);//class 反射.Student
}
4 Class对象的成员变量
- getFields 获取所有public成员变量
- getField 获取单个public成员变量
设置/获取 对象的值 - getDeclaredFields 获取所有成员变量
- getDeclaredField 获取所有成员变量里面的一个
设置/获取 对象的值 - setAccessible //忽略权限
@Test//获取成员变量,set,get成员变量
public void test2() throws NoSuchFieldException, IllegalAccessException {
Class studentClass = Student.class;
//获取所有public成员变量 :getFields
Field[] studentClassFields = studentClass.getFields();
//获取单个public成员变量 :getField
Field studentClassSexField = studentClass.getField("sex");
//获取所有成员变量 :getDeclaredFields
Field[] studentClassDecFields = studentClass.getDeclaredFields();
//获取所有成员变量里面的一个 :getDeclaredField
Field studentClassDecField = studentClass.getDeclaredField("name");
// 获取/设置public成员变量的值
Student student=new Student("aa",1);
Field sexF=studentClass.getField("sex");
Object val= sexF.get(student);//获取
sexF.set(student,22);//设置
//设置非public变量的值,需要设置开启忽略权限
Field nameF=studentClass.getDeclaredField("name");
nameF.setAccessible(true);//忽略权限
Object val2= nameF.get(student);//获取
nameF.set(student,"aaaaaa");//设置
}
5 Class对象的构造方法
- getConstructor
- getDeclaredConstructor
- newInstance创建实例
@Test //获取构成方法,并通过newInstance创建对象
public void test3() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class studentClass = Student.class;
//获取有参构成器
Constructor stuCons1 = studentClass.getConstructor(String.class, int.class);
//通过获取的有参构造器创建对象:newInstance
Object stu1 = stuCons1.newInstance("a", 1);
//获取默认无参构造
Constructor stuCons2 = studentClass.getConstructor();
Object stu2 = stuCons2.newInstance();
//同理 getDeclaredConstructor
//...
}
6 Class对象的成员方法
- getMethods
- getMethod
- getDeclaredMethod
- getDeclaredMethods
- invoke方法
@Test //Class对象的成员方法
public void test4() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class studentClass = Student.class;
Student student = new Student("aa", 1);
//获取指定名称的public方 getMethod
Method speak = studentClass.getMethod("speak");//(无参)
Method speakWords = studentClass.getMethod("speakWords", String.class);//(有参)
//执行方法
speak.invoke(student);
speakWords.invoke(student, "你好啊");
//同理
//getMethods
//getDeclaredMethod
//getDeclaredMethods
}
7 总结
类 :Student
Class类对象:Student.class
通过三种方式可以获类
的Class类对象
,并且可以通过Class类对象
对类进行操作。
- 成员变量
- 构造函数
- 成员方法
- getxxx为获取public的
- getDeclaredxxx 为获取所有的
- 想要访问非public的时候设置setAccessible(true)忽略访问权限