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
Was this helpful?