一、反射简介
(一)什么是反射
Java的反射 (reflection) 机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
(二)反射能做什么
1、在运行时判断任意一个对象所属的类;
2、在运行时构造任意一个类的对象;
3、在运行时判断任意一个类所具有的成员变量和方法;
4、在运行时调用任意一个对象的方法;
5、生成动态代理。
(三)为什么需要反射机制
1、动态类型、静态类型语言
动态类型语言:所谓动态类型语言,就是类型的检查是在运行时才做。动态类型在解释语言中极为普遍,如JavaScript、Python、Ruby等等。
静态类型语言:静态类型语言的类型检查是在运行前的编译阶段,比如C#、Java 等都是静态类型语言,静态类型语言为了达到多态会采取一些类型鉴别手段,如继承、接口,而动态类型语言却不需要。Java是在编译时期确定的变量类型且在运行时期不能改变,在类型转换方面也是强制的,例如大范围整数类型转换为小范围整数类型时必须要强转,如int必须强制转换才能得到小范围类型byte;所以Java是静态、强类型语言。
但是 JAVA 有着一个非常突出的动态相关机制一Reflection(反射),用在Java身上指的是可以于运行时加载、探知、使用编译期间完全知的 classes。换句话说,Java程序可以加载一个运行时才得知名称的 class 获悉其完整构造(但不包括methods定义),并生成其对象例(newlnstance) 或对其 fields 设值,或唤起 (invoke) 其methods方法。
2、开闭原则
为什么在这里提开闭原则,是因为反射也能够在不修改源码的情况下对原有代码进行 ”功能增强“。
Software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification。即:软件实体(模块、类、方法等) 应该“对扩展开放、对修改关闭”。抽象化是开闭原则的关键。 对可变性进行封装是实现抽象化的方法。
即添加一个新的功能应该是,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法 等)。
二、反射引入
假设有下面的类 Person,我们在配置文件中存储了这个类的位置信息以及里面含有的方法。下面的要求就是在不知道这个 Person 类的内部情况下如何创建它的实例对象并且调用里面的方法。
classfullpath = com.purearc.bringin.Cat
method = hi
/**
* date: 2023/6/25
* 省略 getter、setter 和有参无参 Constructor
* @author Arc
*/
package com.purearc.bringin;
public class Cat {
private String name = "defaultName";
public int age = 10;
public void hi(){
System.out.println("sayHi");
}
}
首先就是读取 properties 文件,通过 I/O 流读取到内存中(读取进去是以 map 的键值对形式存储)根据 key 获取 value 值之后转化成 String 字符串我们就在不打开文件的情况下获取了 Person 的全路径类名和它内部的方法名。
/**
* date: 2023/6/25
*
* @author Arc
*/
package com.purearc.bringin;
public class ReflectBringIn {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
properties.load(new FileInputStream("src/main/resources/re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String methodName = properties.get("method").toString();
//System.out.println(classfullpath);
//System.out.println(method);
}
}
下一步就是通过 java 的反射机制来达到构造实例对象、调用成员方法的过程:
1、通过 Class 类的静态方法 forName(String param); 获得一个 cls 对象,该对象的类型就是 Class,就相当于我的名字叫“名字”;
2、通过 cls 对象的 newInstance(); 方法获得一个 Object 对象的实例 o;
3、通过 cls 对象的 getMethond(); 方法获得 Person 的内置方法,返回的是一个 Methond 的类对象,就相当于把 “方法” 也看作是 “对象”,在反射中再一次印证了 “Java 中一切皆对象” 这句话。
标签:反射,Java,System,public,println,机制,out,Class,cls From: https://www.cnblogs.com/purearc/p/17517415.html