抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

反射

作为架构的核心工具, 实现注解, 代理, 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");
    }
}

评论