Java反射
2021-02-03 13:17
标签:class类 安全 idt 字符 利用反射 value 配置文件 field 由来 1.概念: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。 例如:
熟悉一下加载的时候:Class对象的由来是将class文件读入内存,并为之创建一个Class对象。 类的正常加载过程:
2.好处: 反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释。 一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。 上面这样子进行类对象的初始化,我们可以理解为「正」。 而反射则是一开始并不知道我要初始化的类对象是什么,自然也无法使用 new 关键字来创建对象了。 这时候,我们使用 JDK 提供的反射 API 进行反射调用: 所以说什么是反射?反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。 一个简单的例子: 从代码中可以看到我们使用反射调用了 setPrice 方法,并传递了 6000 的值。之后使用反射调用了 getPrice 方法,输出其价格。上面的代码整个的输出结果是: 从这个简单的例子可以看出,一般情况下我们使用反射获取一个对象的步骤: 而如果要调用某一个方法,则需要经过下面的步骤: 到这里,我们已经能够掌握反射的基本使用。但如果要进一步掌握反射,还需要对反射的常用 API 有更深入的理解。 Java反射 标签:class类 安全 idt 字符 利用反射 value 配置文件 field 由来 原文地址:https://www.cnblogs.com/aaaazzzz/p/12801160.html一、什么是反射?
二、反射与正射
三、使用
一、什么是反射?
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法。所以先要获取到每一个字节码文件对应的Class类型的对象.。反射就是把Java类中的各种成分映射成一个个的Java对象。
一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。(其实:一个类中这些成员方法、构造方法,在加入类中都有一个类来描述)
如图是类的正常加载过程:反射的原理在于class对象。
二、反射与正射
如:1 Phone phone = new Phone(); //直接初始化,「正射」
2 phone.setPrice(4);
1 Class clz = Class.forName("com.xxp.reflect.Phone");
2 Method method = clz.getMethod("setPrice", int.class);
3 Constructor constructor = clz.getConstructor();
4 Object object = constructor.newInstance();
5 method.invoke(object, 4);
上面提到的示例程序,其完整的程序代码如下: 1 public class Phone {
2 private int price;
3 public int getPrice() {
4 return price;
5 }
6 public void setPrice(int price) {
7 this.price = price;
8 }
9
10 public static void main(String[] args) throws Exception{
11 //正常的调用
12 Phone phone = new Phone();
13 phone.setPrice(5000);
14 System.out.println("Phone Price:" + phone.getPrice());
15 //使用反射调用
16 Class clz = Class.forName("com.xxp.api.Phone");
17 Method setPriceMethod = clz.getMethod("setPrice", int.class);
18 Constructor phoneConstructor = clz.getConstructor();
19 Object phoneObj = phoneConstructor.newInstance();
20 setPriceMethod.invoke(phoneObj, 6000);
21 Method getPriceMethod = clz.getMethod("getPrice");
22 System.out.println("Phone Price:" + getPriceMethod.invoke(phoneObj));
23 }
24 }
1 Phone Price:5000
2 Phone Price:6000
1 //获取类的 Class 对象实例
2 Class clz = Class.forName("com.xxp.api.Phone");
3 //根据 Class 对象实例获取 Constructor 对象
4 Constructor phoneConstructor = clz.getConstructor();
5 //使用 Constructor 对象的 newInstance 方法获取反射类对象
6 Object phoneObj = phoneConstructor.newInstance();
1 //获取方法的 Method 对象
2 Method setPriceMethod = clz.getMethod("setPrice", int.class);
3 //利用 invoke 方法调用方法
4 setPriceMethod.invoke(phoneObj, 6000);
三、使用
1 * 获取Class对象的方式:
2 1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
3 * 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
4 2. 类名.class:通过类名的属性class获取
5 * 多用于参数的传递
6 3. 对象.getClass():getClass()方法在Object类中定义着。
7 * 多用于对象的获取字节码的方式
8
9 * 结论:
10 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
1 * Class对象功能:
2 * 获取功能
3 1. 获取成员变量们
4 2. 获取构造方法们
5 3. 获取成员方法们
6 4. 获取全类名
7
8 * 获取功能:
9 1. 获取成员变量们
10 * Field[] getFields() :获取所有public修饰的成员变量
11 * Field getField(String name) 获取指定名称的 public修饰的成员变量
12
13 * Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
14 * Field getDeclaredField(String name)
15 2. 获取构造方法们
16 * Constructor>[] getConstructors()
17 * Constructor
* Field:成员变量
* 操作:
1. 设置值
* void set(Object obj, Object value)
2. 获取值
* get(Object obj)
3. 忽略访问权限修饰符的安全检查
* setAccessible(true):暴力反射
* Constructor:构造方法
* 创建对象:
* T newInstance(Object... initargs)
* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
* Method:方法对象
* 执行方法:
* Object invoke(Object obj, Object... args)
* 获取方法名称:
* String getName:获取方法名