Reflect 反射
Java 反射机制 是众多 框架的基础, 包括 MyBatis, Spring。
什么是反射?
反射 是在运行时动态访问类与对象的技术。一般情况下,新建一个对象需要用到 new 关键字。实际上, new 一个对象是写死在程序中的,不够灵活。有的业务场景, 并不知道什么时候能要实例化一个对象,也不知道应该实例化哪个对象。
举个例子。比如有这么一个 MathOperation, 用来处理两个 整形 数字的运算。
public interface MathOperation {
public float operate(int a , int b);
}
有一个 Addition 类实现了 MathOperation 接口, 用于计算 两个整型数字相加并返回结果。
//加法
public class Addition implements MathOperation {
@Override
public float operate(int a , int b) {
System.out.println("执行加法运算");
return a + b;
}
}
还有一个 Subtraction 类实现了 MathOperation 接口, 用于计算 两个整型数字相加并返回结果。
//减法
public class Subtraction implements MathOperation{
@Override
public float operate(int a, int b) {
System.out.println("执行减法运算");
return a - b;
}
}
我们写了一个测试类ReflectionDemo, 里面的有一个case1函数用来测试 Addition 和 Subtraction 功能 。case1 函数的功能非常简单, 在控制台输入运算种类, 然后输入两个数字 a 和 b ,实例化运算功能的对象,然后运算。
public class ReflectDemo {
//不使用 反射, 在编译时决定创建哪几个对象
public static void case1(){
System.out.print("请输入运算名:");
Scanner scanner = new Scanner(System.in);
String op = scanner.next();
System.out.print("请输入a:");
int a = scanner.nextInt();
System.out.print("请输入b:");
int b = scanner.nextInt();
MathOperation mathOperation = null;
if(op.equals("Addition")){
mathOperation = new Addition();
}else if(op.equals("Subtraction")) {
mathOperation = new Subtraction();
}else{
System.out.println("无效的计算类");
return;
}
float result = mathOperation.operate(a, b);
System.out.println(result);
}
public static void main(String[] args) {
case2();
}
}
这里实例化运算对象是写死在case1函数里面的,在编译这段代码时,计算机就已经知道接下来要实例化哪几个类。
假设我们需要新增加计算种类,比如 乘法: a*b , 除法: a/b,指数 a^b, 对数: loga,等等,我们只能在if-else 语句里面不断增加 else if 进行判断, 非常地麻烦。
有没有什么机制,可以在控制台输入运算名之前先不进行创建对象,或者是即使增加了很多运算种类,也不额外增加调用部分的代码。
答案是有的,Java 反射机制 可以解决这个问题。
第一段 Java 反射代码
我们在 ReflectDemo 类中追加一个 case2 函数。
//使用 反射, 动态创建类
public static void case2(){
System.out.print("请输入运算名:");
Scanner scanner = new Scanner(System.in);
String op = scanner.next();
System.out.print("请输入a:");
int a = scanner.nextInt();
System.out.print("请输入b:");
int b = scanner.nextInt();
MathOperation mathOperation = null;
//用反射 机制 动态决定 创建哪一个 对象
try {
mathOperation = (MathOperation) Class.forName("indi.chester.reflectdemo." + op).newInstance();
}catch(Exception e){
System.out.println("无效的计算类");
return;
}
float result = mathOperation.operate(a, b);
System.out.println(result);
}
case2 与 case1 函数大多数代码都是相同的,主要区别在于下面这一行行代码:
mathOperation = (MathOperation) Class.forName("indi.chester.reflectdemo." + op).newInstance();
这一行代码用到了一个 Class类里面的静态方法 forName( String className), 返回一个Class 对象,然后再利用这个 Class 对象调用 newInstance() 方法创建一个对象,返回的 Object 类型对象,需要对其进行强制类型转换,得到一个运算类型对象,也就是 Addition 对象 或者是 Subtraction 对象。
可以看出,在代码编译的时候, 程序并不知道应该创建哪几个对象,完全要等到在控制台输入后程序才知道。
以后无论我们增加 多少种 运算种类, case2 函数都不需要做任何改动, 实现了程序的可复用性和解耦。
Last updated