-
目录
1.反射的概述
2.学习反射到底学什么?
3.字节码文件和字节码文件对象
4.获取字节码文件对象的三种方式
5.Class类中用于获取构造方法的方法
6.Class类中用于获取成员变量的方法
7.Class类中用于获取成员方法的方法
8.反射和配置文件结合动态获取的练习与利用反射保存对象中的信息练习(重点)
9.动态代理
-
1.反射的概述
- 1.1专业解释
- 是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
- 对于任意一个对象,都能够调用它的任意属性和方法;
- 这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
- 1.2通俗的理解
- 利用反射创建的对象可以无视修饰符调用类里面的内容
- 可以跟配置文件结合起来使用,把要创建的对象信息和方法写在配置文件中。
- 读取到什么类,就创建什么类的对象
- 读取到什么方法,就调用什么方法
- 此时当需求变更的时候不需要修改代码,只要修改配置文件即可。
- 1.1专业解释
-
2.学习反射到底学什么?
- 反射允许对成员变量,成员方法和构造方法的信息进行编程访问
- 反射都是从class字节码文件中获取的内容。
- 如何获取class字节码文件的对象
- 利用反射如何获取构造方法(创建对象)
- 利用反射如何获取成员变量(赋值,获取值)
- 利用反射如何获取成员方法(运行)
- 反射应用的两个方向
- 第一个方向:无视修饰符访问类中的内容。但是这种操作在开发中一般不用,都是框架底层来用的。
- 第二个方向:反射可以跟配置文件结合起来使用,动态的创建对象,动态的调用方法。
-
3.字节码文件和字节码文件对象
- java文件:就是我们自己编写的java代码。
- 字节码文件:就是通过java文件编译之后的class文件(是在硬盘上真实存在的,用眼睛能看到的)
- 字节码文件对象:当class文件加载到内存之后,虚拟机自动创建出来的对象。
- 这个对象里面至少包含了:构造方法,成员变量,成员方法。
- 而我们的反射获取的是什么?字节码文件对象,这个对象在内存中是唯一的。
-
4.获取字节码文件对象的三种方式
- 3.1Class这个类里面的静态方法forName(“全类名”)(最常用)
- Class clazz1 = Class.forName("com.itheima.reflectdemo.Student");
全类名 = 包名 + 类名
- 注解:
- 源代码阶段获取 --- 先把Student加载到内存中,再获取字节码文件的对象
- clazz 就表示Student这个类的字节码文件对象。
- 就是当Student.class这个文件加载到内存之后,产生的字节码文件对象
- Class clazz1 = Class.forName("com.itheima.reflectdemo.Student");
- 3.2通过class属性获取
- Class clazz2 = Student.class;
- 3.3通过对象获取字节码文件对象
- Student s = new Student();
- Class clazz3 = s.getClass();
- 3.4注意:
- 因为class文件在硬盘中是唯一的,所以,当这个文件加载到内存之后产生的对象也是唯一的
- System.out.println(clazz1 == clazz2);//true
- System.out.println(clazz2 == clazz3);//true
- 3.1Class这个类里面的静态方法forName(“全类名”)(最常用)
-
5.Class类中用于获取构造方法的方法
- 5.1方法名
- Constructor<?>[] getConstructors()
获得所有的构造(只能public修饰)
- Constructor<?>[] getDeclaredConstructors()
获得所有的构造(包含private修饰)
- Constructor<T> getConstructor(Class<?>... parameterTypes)
获取指定构造(只能public修饰)
- Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
获取指定构造(包含private修饰)
Constructor con4 = clazz.getDeclaredConstructor(String.class);
- Constructor<?>[] getConstructors()
- 5.2获取构造方法并创建对象
- 涉及到的方法:newInstance(创建对象)与setAccessible(临时修改构造方法的访问权限)
- 代码示例:JavaBean类
- 代码示例:测试类
- 5.1方法名
-
6.Class类中用于获取成员变量的方法
- 6.1方法名
- Field[] getFields()
返回所有成员变量对象的数组(只能拿public的)
- Field[] getDeclaredFields()
返回所有成员变量对象的数组,存在就能拿到
- Field getField(String name)
返回单个成员变量对象(只能拿public的)
- Field getDeclaredField(String name)
返回单个成员变量对象,存在就能拿到
- Field[] getFields()
- 6.2获取成员变量并获取值和修改值
- void set(Object obj, Object value)
赋值 :参数一:表示要修改哪个对象的name? 参数二:表示要修改为多少?
- Object get(Object obj)
获取值
- 代码示例:
- void set(Object obj, Object value)
- 6.1方法名
-
7.Class类中用于获取成员方法的方法
- 7.1方法名
- Method[] getMethods()
返回所有成员方法对象的数组(只能拿public的)
getMethods可以获取父类中public修饰的方法
- Method[] getDeclaredMethods()
返回所有成员方法对象的数组,存在就能拿到
- Method getMethod(String name, Class<?>... parameterTypes)
返回单个成员方法对象(只能拿public的)
- Method getDeclaredMethod(String name, Class<?>... parameterTypes)
返回单个成员方法对象,存在就能拿到
- Method[] getMethods()
- 7.2获取成员方法并运行
- Object invoke(Object obj, Object... args) :运行方法
- 参数一:用obj对象调用该方法
- 参数二:调用方法的传递的参数(如果没有就不写)
- 返回值:方法的返回值(如果没有就不写)
- 代码示例:JavaBean类
- 代码示例:测试类
- 7.1方法名
-
8.反射和配置文件结合动态获取的练习与利用反射保存对象中的信息练习(重点)
- 8.1配置文件
- 好处:1. 可以把软件的设置永久化存储 2. 如果我们要修改参数,不需要改动代码,直接修改配置文件就可以了
- properties配置文件
- 重点:1. properties是一个双列集合,拥有Map集合所有的特点 2. 有一些特有的方法,可以把集合中的数据,按照键值对的形式写到配置文件当中。也可以把配置文件中的数据,读取到集合中来。
- 8.2需求:利用反射根据文件中的不同类名和方法名,创建不同的对象并调用方法。
- 8.3分析:
- ①通过Properties加载配置文件
- ②得到类名和方法名
- ③通过类名反射得到Class对象
- ④通过Class对象创建一个对象
- ⑤通过Class对象得到方法
- ⑥调用方法
- 8.4示例代码
- 8.5利用反射保存对象中的信息练习
- 8.1配置文件
-
9.动态代理
- 9.1动态代理的功能
- 可以无侵入式的给对象增强其他的功能(调用者 --> 代理 --> 对象)
- 9.2Java通过什么来保证代理的样子
- 通过接口保证,后面的对象和代理需要实现同一个接口,接口中就是被代理的所有方法
- 9.3动态代理三要素:
- 1,真正干活的对象
- 2,代理对象
- 3,利用代理调用方法
- 9.4如何创建一个代理对象?
- java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法
- public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
参数一:用于指定用哪个类加载器,去加载生成的代理类
参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
参数三:用来指定生成的代理对象要干什么事情
- 9.5代码示例
- 代码示例
- 9.1动态代理的功能