ZT 理解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") 将导致名为 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都是这样的. 在Web与EJB间, 他们的classLoader就是不同的,这样做的目的就是为了避免两者间类装载的相互干扰。
是否实例化类
Class的装载分了三个阶段,loading(装载),linking(连接)和initializing(实例化)分别定义在The Java Language Specification的12.2,12.3和12.4。
Class.forName(className)实际上是调用Class.forName(className, true, this.getClass().getClassLoader())。注意第二个参数,是指Class被loading后是不是必须被初始化。
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!");
}
}
可以看到,Driver在static块中会注册自己到java.sql.DriverManager。而static块就是在Class的初始化中被执行。所以这个地方就只能用Class.forName(className)。
资源
http://blog.csdn.net/longdick/article/details/1873795
ZT 理解class.forName()的更多相关文章
- ZT 理解 Android 上的安全性
理解 Android 上的安全性 http://www.ibm.com/developerworks/cn/xml/x-androidsecurity/ 利用沙箱.应用程序签名和权限增强应用程序安全性 ...
- 理解class.forName()
使用jdbc方式连接数据库时会使用一句代码Class.forName(String className).这句话是什么意思呢?首先说一点Class.forName(String className)这 ...
- 理解class.forName()(转)
使用jdbc方式连接数据库时会使用一句代码Class.forName(String className).这句话是什么意思呢?首先说一点Class.forName(String className)这 ...
- 理解class.forName()(good--字节码层面)
使用jdbc方式连接数据库时会使用一句代码Class.forName(String className).这句话是什么意思呢?首先说一点Class.forName(String className)这 ...
- 理解class.forName() ---使用jdbc方式链接数据库时会经常看到这句代码
目录(?)[-] 官方文档 类装载 两种装载方法的区别 不同的类装载器 是否实例化类 在jdbc链接数据库中的应用 资源 原文地址:http://yanwushu.sinaapp.com/clas ...
- Class类是什么? Class.forName()是干什么的?
Class类概念 Class类用来描述一个类的结构,比如描述一个类有哪些成员,有哪些方法等.有多种方法可以获取一个类对应的Class类实例,比如: //第一种方式获取描述Dog类结构的Class类实例 ...
- JDBC连接数据库步骤及Class.forName()(转)
JDBC连接数据库 JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java DataBase Connectivity,java数据库连接)是一种 ...
- 别翻了,这篇文章绝对让你深刻理解java类的加载以及ClassLoader源码分析【JVM篇二】
目录 1.什么是类的加载(类初始化) 2.类的生命周期 3.接口的加载过程 4.解开开篇的面试题 5.理解首次主动使用 6.类加载器 7.关于命名空间 8.JVM类加载机制 9.双亲委派模型 10.C ...
- 关于Java反射机制的几个问题
>>如何在运行时确定对象类型 运行时类型识别(Run-time Type Identification, RTTI)主要有两种方式, 一种是在编译时和运行时已经知道了所有的类型,另外一种是 ...
随机推荐
- Hadoop Metrics2
来源:Hadoop Metrics2 Metrics are collections of information about Hadoop daemons, events and measureme ...
- @Scheduled执行定时任务与cron表达式
1 配置文件形式执行定时任务 1 1.X 版本与spring结合使用实例 1.1 常用maven管理 pom.xml文件 <project xmlns="http://maven.ap ...
- 多功能电子通讯录(涉及到了双向链表的使用,Linux文件编程等等)
readme.txt //作为一个程序员,我们咋么能不写用户手册呢!MSP的我觉得用户体验是王道,苹果手机的用户体验的确不错!不过WP加油!我去,扯远了!赶紧看我的程序吧! 歡迎使用多功能電子通訊錄 ...
- linux shell学习-1
今天在使用$()这个命令的时候,如下,一直纳闷为何输出不是 "/usr": 一直在不断换着法子来试,原来是$()会将每个执行的命令单独隔开来的,及时是嵌套的命令,也会在执行逻辑上单 ...
- AngularJs ng-repeat重复项异常解决方案
ng-repeat="v in arr track by $index" <!DOCTYPE html> <html lang="en"> ...
- unity项目git管理
Unity设置 (关键) Edit -> Project Settings -> Editor -> Version Control Mode 开启 Visible Meta Fil ...
- checkebox 全选 ,子复选框单个全部选择后,全选框也会被选择
<script> //点击全选,子复选框被选中 function demo(){ var allcheck=document.getElementById("allcheck&q ...
- 使用FileSystemWatcher监视指定目录
使用 FileSystemWatcher 监视指定目录中的更改.可监视指定目录中的文件或子目录的更改. 以下是一个简单的实例,用来监控指定目录下文件的新增.删除.重命名等情况(文件内容更改会触发多次, ...
- linux 图解常用的云运维监控工具
随着新技术的不断发展,云服务已经互联网企业的必须,但是长期以来会存在传统物理主机和云主机.私有云和公有云并存的状态.此外,互联网企业的发展速度非常快,小米.滴滴出行等很多企业都是在短短几年内发展起来的 ...
- sublime下package control安装无效解决
使用快捷键:ctrl+`打开控制台执行如下命令 sublime2: import urllib2,os,hashlib; h = 'df21e130d211cfc94d9b0905775a7c0f' ...