• java两种反射的区别


    在理解这两种反射机制之前,需要弄清楚java类的加载机制.

    装载:通过类的全限定名获取二进制字节流(二进制的class文件),将二进制字节流转换成方法区中的运行时数据结构,在内存中生成Java.lang.class对象。这个时候该类型没有被分配内存,设置默认值,也没有初始化。

    链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;

      校验:检查导入类或接口的二进制数据的正确性;(文件格式验证,元数据验证,字节码验证,符号引用验证)

      准备:给类的静态变量分配并初始化存储空间;

      解析:将常量池中的符号引用转成直接引用;

    初始化:激活类的静态变量的初始化Java代码和静态Java代码块,并初始化程序员设置的变量值。

    Class.forName有两个重载方法:

     public static Class<?> forName(String name, boolean initialize,
                       ClassLoader loader)
            throws ClassNotFoundException
    
    
     public static Class<?> forName(String className) 
                    throws ClassNotFoundException

    解释:

    name:类的全限定名,如:com.org.prj
    initialize:如果为true,则会在返回Class对象之前,对该类型做连接,校验,初始化操作。(如:执行static块中的代码),initialize默认需要初始化。
    loader:用自定义的类加载器来请求这个类型;当然,你也可以传入null,用bootstrap加载器

    由于Class.forName默认是需要初始化,一旦初始化,就会触发目标对象的 static块代码执行,static参数也也会被再次初始化。

    我们在来看ClassLoader.loadClass也有两个两个重载方法:

    protected synchronized Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    
    public Class<?> loadClass(String name) throws ClassNotFoundException 

    解释:

    name:类的全限定名,如:com.org.prj

    resolve:表示是否需要连接该类型。 仅仅是连接(这里面包括校验class文件,准备分配内存,类型常量池的替换),并不会初始化该类型。

    resolve默认是不链接,不进行链接意味着不进行包括初始化等一些列步骤,那么静态块和静态对象就不会得到执行。

    总结:

    1.Class.forName返回的Class对象可以决定是否初始化。而ClassLoader.loadClass返回的类型绝对不会初始化,最多只会做连接操作。
    2.Class.forName可以决定由哪个classLoader来请求这个类型。而ClassLoader.loadClass是用当前的classLoader去请求。

  • 相关阅读:
    移动视频开发让我们把会议室装进口袋里
    音视频 开发技术,让智能家居更智能!
    视频对讲SDK 大厅好友解决方案
    视频开发的安全保障措施
    手机视频开发即时通讯软件
    借音视频开发技术,开发招聘新途径
    移动视频技术的先驱
    tf.variable_scope
    sklearn 数据预处理
    Tensorflow自编码器及多层感知机
  • 原文地址:https://www.cnblogs.com/clarke157/p/6651195.html
Copyright © 2020-2023  润新知