反射
作为架构的核心工具, 实现注解, 代理, AOP, ORM等等工具的实现.
程序运行时查看, 反观程序内部结构, 甚至动态修改自己.
比如通过字符串查找元数据,找到某个类并且调用它的方法,去查看一个类有哪些属性和方法,去查看一个类有哪些注解,注解有哪些数据,这些都是反射的能力。
另一个反射提供的能力,就是让程序用自己动态的修改自己。这部分知识牵扯到直接修改Java的字节码
。例如Javassist
框架, 支持运行时再去定义类, 接口, 方法, 然后把定义转换成字节码, 再通过ClassLoader
加载。
- 运行时数据(通常称作元数据 MetaData,例如:Java中模块, 类, 函数, 注解, 源代码都是元数据).
- 反观自身。查看类的方法,属性,注解。
- 运行时修改, 修改的是
ByteCode
(字节码), 实际就是byte[]
. 可以使用javasist
, 在运行时创建class
。
public class ReflectSample {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
// 注意与 loadClass 的区别
Class<?> rc = Class.forName("org.lgq.interview.reflect.Robot");
Robot robot = (Robot) rc.getDeclaredConstructor().newInstance();
System.out.println(rc.getName());
// 不能获取到继承或接口的方法
Method getHello = rc.getDeclaredMethod("throwHello", String.class);
getHello.setAccessible(true);
Object str = getHello.invoke(robot, "Lgq");
System.out.println(str);
Field name = rc.getDeclaredField("name");
name.setAccessible(true);
name.set(robot, "lgq");
Method sayHi = rc.getMethod("sayHi", String.class);
sayHi.invoke(robot, "Welcome");
}
}