zoukankan      html  css  js  c++  java
  • ClassLoader.loadClass()与Class.forName()的区别

    在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步

    除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:

        装载:查找和导入类或接口的二进制数据; 

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

      校验:检查导入类或接口的二进制数据的正确性; 

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

      解析:将符号引用转成直接引用; 

      初始化:激活类的静态变量的初始化Java代码和静态Java代码块。

    Class.forName(className)方法,其实调用的方法是Class.forName(className,true,classloader);注意看第2个boolean参数

    它表示的意思,在loadClass后必须初始化。比较下我们前面准备jvm加载类的知识,我们可以清晰的看到在执行过此方法后,目标对象的 static块代码已经被执行,static参数也已经被初始化

     再看ClassLoader.loadClass(className)方法,其实他调用的方法是ClassLoader.loadClass(className,false);还是注意看第2个 boolean参数,该参数表示目标对象被装载后不进行链接,这就意味这不会去执行该类静态块中间的内容

    最后还有必要在此提一下new方法和newInstance方法的区别

    newInstance: 弱类型。低效率。只能调用无参构造。

    new: 强类型。相对高效。能调用任何public构造。

    例如,在JDBC编程中,常看到这样的用法,Class.forName("com.mysql.jdbc.Driver"),如果换成了 getClass().getClassLoader().loadClass("com.mysql.jdbc.Driver"),就不行。 
    为什么呢?打开com.mysql.jdbc.Driver的源代码看看, 

     Register ourselves with the DriverManager
    static {
        try {
            java.sql.DriverManager.registerDriver(new Driver());
        } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
        }
    } 

    Driver在static块中会注册自己到java.sql.DriverManager。而static块就是在Class的初始化中被执行。所以这个地方就只能用Class.forName(className)。

     

  • 相关阅读:
    hi.baidu.com 百度流量统计
    Autofac is designed to track and dispose of resources for you.
    IIS Manager could not load type for module provider 'SharedConfig' that is declared in administration.config
    How to create and manage configuration backups in Internet Information Services 7.0
    定制swagger的UI
    NSwag在asp.net web api中的使用,基于Global.asax
    NSwag Tutorial: Integrate the NSwag toolchain into your ASP.NET Web API project
    JS变量对象详解
    JS执行上下文(执行环境)详细图解
    JS内存空间详细图解
  • 原文地址:https://www.cnblogs.com/heyjia/p/11338612.html
Copyright © 2011-2022 走看看