框架灵魂——反射

反射是框架设计的灵魂!但是本文并不是什么高深莫测的框架设计,只是对 Java 反射机制的一次简单总结。温故而知新,可以为师矣!

为什么说反射是框架设计的灵魂?其实在学校 Java SE 的时候,并没有去了解反射机制,第一次听说这个名词是在学习 Spring 的时候,其中有两个重要的概念 IOC (动态加载 Bean)和 AOP (动态代理)就是依靠 Java 的反射机制去实现的。除此之外,还有 JDBC 连接数据库时使用 Class.forName() 通过反射加载数据库驱动程序,JDBC 中还使用反射将表字段映射到 Java 对象的 getter/setter 方法的。Jackson、GSON等等类库也是利用反射将 JSON 文件的属性映射到 Java 对象的 getter/setter 方法。

可见反射真的是无处不在!而且是框架设计的灵魂所在!

正文

Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能成为 Java 语言的反射机制。——出自:Java基础之—反射(非常重要)

如何获取 Class 对象?

想要利用反射机制动态的获取类的属性和方法,需要依靠 Class 对象。Class 类对象将一个类的方法、变量等信息都告诉运行的程序。Java 提供了两种方式获取 Class 对象:

  1. 已经有类的情况下:

    Class m1ngClass = M1ng.class;
    
  2. 通过 Class.forName() 拿到 Class 对象:(常用)

    Class m1ngClass = Class.forName("edu.m1ng.test.M1ng");
    

简单感受一下反射机制

待操作的自定义类:

public class M1ng {
    private String name;
    private String like;

    public M1ng() {
        this.name = "m1ng";
        this.like = "coding";
    }

    public void whoami(){
        System.out.println("i am "+name);
    }

    private String like(String name){
        return name + " like " + like;
    }
}

感受一下反射机制的威力:

public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    //拿到 Class 对象并创建实例
    Class<?> m1ngClass = Class.forName("edu.test.M1ng");
    M1ng m1ng = (M1ng) m1ngClass.newInstance();
    
    //获取类中的所有方法(继承自 Object 的方法和自定义的方法)
    Method[] allMethods = m1ngClass.getMethods();
    for (Method method : allMethods) {
        System.out.println(method.getName());
    }
    
    //获取指定方法,并调用
    Method whoami = m1ngClass.getDeclaredMethod("whoami", null);
    Method likeMethod = m1ngClass.getDeclaredMethod("like", String.class);
    whoami.invoke(m1ng);
    
    //获取指定参数并修改
    Field likeField = m1ngClass.getDeclaredField("like");
    likeField.setAccessible(true);
    likeField.set(m1ng,"zqc");
    
    //调用私有方法,需要取消安全检查 设置为可访问的
    likeMethod.setAccessible(true);
    System.out.println(likeMethod.invoke(m1ng,"M1ng"));

}
输出:
whoami
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
i am m1ng
M1ng like zqc

反射机制的优缺点

  • 优点:运行期类型的判断,动态加载类,提高代码灵活度。
  • 缺点:反射需要一系列的解释处理,通知 JVM 要做的事情,性能肯定要比直接使用明确的 Java 代码要慢得多。而且动态操作去改变类的属性也会增加类的安全隐患。

本人菜鸟,有错误请告知,感激不尽!

更多题解和源码:github

猜你喜欢

转载自blog.csdn.net/qq_42758551/article/details/106265305
今日推荐