理解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/118959.html原文链接:https://javaforall.cn

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

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

(0)


相关推荐

  • 公有云和私有云的对比和转换

    公有云和私有云的对比和转换章节目录共5500字,可跳读趣味科普-虾蟹互换私有云同样有底蕴有深度私有云转公有云的真难点公有云转私有云的真难点私有云转公有云的假难题公有云转私有云的假难题两类云人力侧重的不同定制越多越好…

  • jQuery validationEngine自定义提醒

    jQuery validationEngine自定义提醒在网上看了好多自定义验证样式,好多都是不是自己想要的!打开源码,看了一下挺简单的!将下面的样式添加到页面上就可以实现黑色主题的提醒!想要什么样式基本都可以自己修改了!很方便/*验证样式*/.formError.formErrorContent{ width:100%; /*错误提示框颜色*/ background:#000; position:rela

  • python 列表的基本操作

    python 列表的基本操作列表常用方法:name=['zhangsan','lisi','wangwu','xieqi']name2=[1,2,3,4]

  • word怎么把编号变成文本格式_word字离序号特别远

    word怎么把编号变成文本格式_word字离序号特别远记录一下word如何去掉自动编号格式但保留原编号内容的方法:1.调出word的“开发工具”选项打开文件->选项->自定义功能区->选中开发工具->确定,2.编写宏依次点击:开发工具-宏-在“宏名”框内输入宏名(如:NumToTxt)-单击“创建”按钮,弹出VisualBasic编辑器窗口,窗口内自动出现以下内容把下面的这段代码复制下来:ActiveDocument.Content.ListFormat.ConvertNumbersToText粘.

  • Windows 平台搭建 PHP 集成开发环境[通俗易懂]

    Windows 平台搭建 PHP 集成开发环境[通俗易懂]Windows平台搭建PHP集成开发环境安装xamppXAMPP是一个易于安装且包含MySQL、PHP和Perl的Apache发行版。XAMPP的确非常容易安装和使用:只需下载,解压缩,启动即可。官网地址点击下载window版本的安装包,下载完成后点击安装next->next->…完成安装,打开软件:打开Apache服务出现问题:Apache启动提示1

  • Ubuntu 18.04换国内源 中科大源 阿里源 163源 清华源

    Ubuntu 18.04换国内源 中科大源 阿里源 163源 清华源国内有很多Ubuntu的镜像源,包括阿里的、网易的,还有很多教育网的源,比如:清华源、中科大源。我们这里以中科大的源为例讲解如何修改Ubuntu18.04里面默认的源。编辑/etc/apt/sources.list文件,在文件最前面添加以下条目(操作前请做好相应备份):##中科大源debhttps://mirrors.ustc.edu.cn/ubuntu/bionic…

发表回复

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

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