反射:动态引入类、动态调用实例的成员函数、成员变量等。
通过反射机制,可以动态加载代码,
若一段代码需要反复修改,便可以利用反射机制,而不需要像C++一样 重新打包后上传
基本概念这里就不赘述,这里只给出一般用法
常用API,一般使用场景
(1) java.lang.Class 加载类
(2) java.lang.reflect.Method 得到类中的方法
(3) java.lang.reflect.Field 得到类的成员变量
(4) java.lang.reflect.Constructor 调用有参构造函数
例子:
Calculator类:
package org.example.thirdparty;
public class Calculator {
public String name;
public Calculator() {}
public Calculator(String name) {
this.name = name;
}
public int add(int a, int b) {
return a + b;
}
@Override
public String toString() {
return name;
}
}
入口:
package org.example;
import org.example.thirdparty.Calculator;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class<?> cls = Class.forName("org.example.thirdparty.Calculator");//加载类,赋给类对象Class<?>
/*生成类的实例*/
Object o = cls.newInstance();//调用类的无参构造函数, 生成一个类
/*利用反射api getMethod调用方法*/
//如果是直接引用类,不用反射机制去调用类的方法: o.add(3,4)
Method method = cls.getMethod("add", int.class, int.class);
int res = (int)method.invoke(o, 3, 4); //invoke 执行该方法
System.out.println(res);
/*修改遍历:*/
/*一般方法改变类成员遍历,如name:
o.name = ... */
//动态修改名称:
Field field = cls.getField("name"); //成员变量为Field 域, 这里的"name"可以为一个变量,动态修改
field.set(o, "My Calculator!"); //如: String fieldName = "name", fieldName 可以随时改变
System.out.println(field.get(o)); //获取这个变量值
/*调用类的有参构造函数*/
Constructor<?> constructor = cls.getConstructor(String.class); //传入参数类型
Object new_o = constructor.newInstance("New Calculator!"); //创建新实例
System.out.println(new_o);
一般引用类的办法:
Calculator o = new Calculator();
System.out.println(o.add(3,4));
o.name = "My Calculator";
System.out.println(o.name);
Calculator newObeject = new Calculator("New Calculator!");
System.out.println(newObeject);
结构图如下: