理解class.forName()

理解class.forName()

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

使用jdbc方式连接数据库时会使用一句代码Class.forName(String className).这句话是什么意思呢?首先说一点Class.forName(String className)这种方法的作用是装载className这个字符串指定的类。


官方文档


返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:

  Class.forName(className, true, currentLoader)

 当中 currentLoader 表示此类的定义类载入器。

比如,下面代码片段返回 java.lang.Thread 类的执行时 Class 描写叙述符。

   Class t = Class.forName(“java.lang.Thread”)

 调用 forName(“X”) 将导致名为 的类被初始化。

參数:

className – 所需类的全然限定名。

返回:

具有指定名的类的 Class 对象。

通俗的说就是:获得字符串參数中指定的类,并初始化该类

类装载


类装载就是把一个类或是一个接口的字节码文件,通过解析该字节码来构建代表这个类或是这个接口的实例的过程。 这个字节码文件来源可能是压缩包、网络、执行时编译出的或者自己主动生成的class文件,jvm spec没有规定必须从什么地方载入。

类装载的两种方式:

1.Class c1 = Class.forName (“java.lang.String”); 

2.ClassLoader cl = new  ClassLoader(); 

Class cl.loadClass( String name, boolean resolve );

两种装载方法的差别:


不同的类装载器


  Class.forName是从指定的classloader中装载类,假设没有指定,也就是一个參数的时候,是从装载当前对象实例所在的classloader中装载类

  而ClassLoader的实例调用loadclass方法,是指从当前ClassLoader实例中调用类,而这个实例与装载当前所在类实例的Classloader或许不是同一个

      说白了就是他们实现装载的时候,使用的类装载器的指定是不同的。那为什么使用不同的ClassLoader来装载类呢?

      事实上使用多个classloader载入类的情况很常见,比方说我们的app server都是这种WebEJB他们的classLoader就是不同的,这样做的目的就是为了避免两者间类装载的相互干扰

是否实例化类


      Class的装载分了三个阶段,loading(装载),linking(连接)和initializing(实例化)分别定义在The Java Language Specification12.212.312.4

 Class.forName(className)实际上是调用Class.forName(className, true, this.getClass().getClassLoader())。注意第二个參数,是指Classloading后是不是必须被初始化。

    ClassLoader.loadClass(className)实际上调用的是ClassLoader.loadClass(name, false),第二个參数指出Class是否被link

    差别就出来了。Class.forName(className)装载的class已经被实例化,而ClassLoader.loadClass(className)装载的class还没有被link,所以就更谈不上实例化了。

  普通情况下,这两个方法效果一样,都能装载Class。但假设程序须要Class实例化,就必须用Class.forName(name)了。

比如,在JDBC中载入mysql的驱动类时(关于注冊jdbc驱动请參看另外一篇文章,jdbc注冊驱动的三种方式)Class.forName(“com.mysql.jdbc.Driver”),假设换成getClass().getClassLoader().loadClass(“com.mysql.jdbc.Driver”),就不行,由于它仅仅是向jvm装载了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!”);

    }

}

能够看到,Driverstatic块中会注冊自己到java.sql.DriverManager。而static块就是在Class的初始化中被运行。所以这个地方就仅仅能用Class.forName(className)


资源


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118332.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • html psd设计图,根据PSD登陆页面设计稿切图制作HTML网页全过程

    html psd设计图,根据PSD登陆页面设计稿切图制作HTML网页全过程切图的目的是把PSD设计稿转换为HTML页面。记得自己当时学习切图时,网上切图相关的文章是不少,但是大都是讲怎么使用切片工具把一张图片分割成多张图片,然后存储为Web使用格式,并且都比较简单和零碎,并不能满足我的要求。因此只能自己不断尝试,今天分享给大家“如何根据PSD设计稿通过PS切图和DIV+CSS布实现HTML页面”,希望能帮助到大家。实例:下面通过一个简单的登陆页面PSD设计稿来演示转化为…

  • 软件的三层架构

    软件的三层架构

    2021年12月14日
  • Python进制转换与ASCII转换

    Python进制转换与ASCII转换本文结合实际应用和刷Leetcode总结了Python的一些常用的方法一、字符串二、列表三、字典其他input()用于获取用户的输入值,返回一个字符串类型例:msg=input(‘请输入值’)…

  • ollydbg激活成功教程教程_逆向教程分享

    ollydbg激活成功教程教程_逆向教程分享目录一、OllyDbg基本知识1.1简介1.2窗口界面1.2.1窗口组成1.2.2窗口功能1.3常用快捷键二、测试修改实例2.1测试内容2.2测试环境2.3测试程序2.4测试步骤2.4.1将程序载入OD2.4.2定位内存地址2.4.3修改内容2.5测试结果三、小结一、OllyDbg基本知识1.1简介OllyDbg是一种具有可视化界面的汇编分析调试器,是一个支持插件扩展功能的动态追踪工具。1.2窗口界面1.2.1窗口组…

  • 闭包面试回答_ajax面试题

    闭包面试回答_ajax面试题写在前面:在学习了闭包之后,试着做做这些题。其实是一种很棒地检验自己学习成果的手段。我当时反反复复,学了但好像又没完全学,遇到题还是一头雾水,到现在可以捋得很清楚也经历了蛮久的。而且从this,执行上下文,作用域一直走过来,这些题目涉及的内容也相对全面,加油喽。

  • Log4J 配置文件 指定类 properties

    Log4J 配置文件 指定类 properties

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号