• Java反射的好处


    反射的好处

    我们在第一次接触反射的时候,总会有个很大的疑问,反射看起来好麻烦啊,各种get.get,他究竟有什么好处,能用来做什么呢?

    我们先来看一下《编程思想》这本书中是怎么说的.

    RTTI和反射之间真正的区别只在于,对RTTI来说,编译器在在编译时打开和检查.class文件.(换句话说,我们可以用"普通"方式调用对象的所有方法).对于反射机制来说,.class文件在编译时是不可获取的,所以在运行时打开和检查.class文件。 --《编程思想》

    这段话看起来很叼的样子,有点云里雾里的,首先RTTI的意思就是以普通的方式来创建对象,调用方法,就是我们常用的new关键字。这段话的意思简化版就是:编译器将.java文件编译成.class文件之后,普通方式创建的对象就不能再变了,我只能选择是运行还是不运行这个.class文件。是不是感觉很僵硬,假如现在我有个写好的程序已经放在了服务器上,每天供人家来访问,这时候Mysql数据库宕掉了,改用Oracle,这时候该怎么怎么办呢?假如没有反射的话,我们是不是得修改代码,将Mysql驱动改为Oracle驱动,重新编译运行,再放到服务器上。是不是很麻烦,还影响用户的访问。

    假如我们使用反射Class.forName()来加载驱动,只需要修改配置文件就可以动态加载这个类,Class.forName()生成的结果在编译时是不可知的,只有在运行的时候才能加载这个类,换句话说,此时我们是不需要将程序停下来,只需要修改配置文件里面的信息就可以了。这样当有用户在浏览器访问这个网站时,都不会感觉到服务器程序程序发生了变化。

    所以在《Mybatis技术原理与实战》是这么说反射的好处的。

    配置性大大提高,如同Spring IOC容器,给很多配置设置参数,使得java应用程序能够顺利跑起来,大大提高了Java的灵活性和可配置性,降低模块间的耦合。--《Mybatis技术原理与实战》

    相应的实例

    Eclipse的代码自动补全就是利用了反射原理动态的加载要展示的方法,因为反射会影响性能,所以开了自动补全刚开始的时候会卡一下,主要还是我电脑性能不行。

    反射的进阶

    在JDK动态代理中可以利用反射直接获取到接口的方法来执行,从而可以将代理类要处理的代码抽象出来形成统一的接口。

    Java的反射中Class.forName和ClassLoader的区别

    ClassLoader:

    ClassLoader就是遵循双亲委派模型最终调用启动类加载器的类加载器,实现的功能是“通过一个类的全限定名来获取描述此类的二进制字节流”,获取到二进制流后放到JVM中。
    例如ClassLoader.getSystemClassLoader().loadClass("com.test.mytest.ClassForName");是不会初始化类的。

    Class.forName():

    Class.forName()方法实际上也是调用的CLassLoader来实现的。
    Class.forName(String name, boolean initialize,ClassLoader loader)方法来手动选择在加载类的时候是否要对类进行初始化。

    应用场景:

    1. 在我们熟悉的Spring框架中的IOC的实现就是使用的ClassLoader。

    2. 使用JDBC时通常是使用Class.forName()方法来加载数据库连接驱动。这是因为在JDBC规范中明确要求Driver(数据库驱动)类必须向DriverManager注册自己

    public class Driver extends NonRegisteringDriver implements java.sql.Driver {  
        // Register ourselves with the DriverManager  
        static {  
            try {  
                java.sql.DriverManager.registerDriver(new Driver());  
            } catch (SQLException E) {  
                throw new RuntimeException("Can't register driver!");  
            }  
        }  
        public Driver() throws SQLException {  
            // Required for Class.forName().newInstance()  
        }  
    }
    

    Class.forName()会初始化类,所以自动加载static代码段,从而注册自己。

  • 相关阅读:
    oracle session和process的关系
    Oracle 连接、会话数的查看,修改
    Oracle 中session和processes的初始设置
    Oracle 修改字段注释
    Oracle创建自增字段和修改方法-ORACLE SEQUENCE的简单介绍
    Oracle 字段类型
    ORA-01591错误的原因和处理方法
    Oracle 优化器
    Oracle 使用TRUNCATE TABLE删除所有行
    Oracle中Hint深入理解(原创)
  • 原文地址:https://www.cnblogs.com/bihanghang/p/9992237.html
Copyright © 2020-2023  润新知