Class.forName与ClassLoader(转)
来源:互联网 发布:bernsen二值化算法 编辑:程序博客网 时间:2024/06/14 19:54
Class 用来描述一个类型,当一个类型被装载(虚拟机读取二进制的class文件)的时候,会创建一个与该类型对应的Class对象到内存堆中。(这个时候该类型甚至没有被分配内存,设置默认值,更别说初始化了)。
Class.forName有2个重载的方法:
第一个方法:
name:类的全限定名,如:com.aaa.bbb.ccc
initialize:如果为true,则会在返回Class对象之前,对该类型做连接,校验,初始化操作。(如:执行static块中的代码)
loader:用自定义的类加载器来请求这个类型;当然,你也可以传入null,用bootstrap加载器。
第二个方法:
name和上面相同。默认initialize为true,
而loader是这么获取的
其实就是获取当前类的classLoader,也就是装载执行forName操作的类的classLoader
类ClassLoader包括2个重载的loadClass类
两个方法都需要传name,既类的全限定名作为参数。
resolve:表示是否需要连接该类型。
注意:是连接(这里面包括校验class文件,准备分配内存,类型常量池的替换),并不会初始化该类型。
看源码可以看到,resolve也只是调用了一下resolveClass这个方法
都说清楚了,也很容易区分出不同点:
1.Class.forName返回的Class对象可以决定是否初始化。而ClassLoader.loadClass返回的类型绝对不会初始化,最多只会做连接操作。
2.Class.forName可以决定由哪个classLoader来请求这个类型。而ClassLoader.loadClass是用当前的classLoader去请求。
举个例子吧:
JDBC的注册驱动大家都狠熟悉吧:
为啥是要用Class.forName?
首先看看注册驱动是什么意思。
打开DriverManager的代码,可以看到这个方法:
如果要注册驱动,必须得这么来
而这行代码,都是写在驱动的实现类,而且是一个static块来加载的。
所以随便找一个jdbc驱动程序的代码,肯定会有这样的实现
用来注册驱动程序到DriverManager,这样驱动才能使用。
由于static块是属于类的,所以,此处仅仅需要初始化类即可。不需要具体实例。
那么用
再合适不过了。
而ClassLoader由于不会初始化类。明显不行。
Class.forName有2个重载的方法:
- public static Class<?> forName(String name, boolean initialize,
- ClassLoader loader)
- throws ClassNotFoundException
- public static Class<?> forName(String className)
- throws ClassNotFoundException
第一个方法:
name:类的全限定名,如:com.aaa.bbb.ccc
initialize:如果为true,则会在返回Class对象之前,对该类型做连接,校验,初始化操作。(如:执行static块中的代码)
loader:用自定义的类加载器来请求这个类型;当然,你也可以传入null,用bootstrap加载器。
第二个方法:
name和上面相同。默认initialize为true,
而loader是这么获取的
- ClassLoader.getCallerClassLoader()
其实就是获取当前类的classLoader,也就是装载执行forName操作的类的classLoader
类ClassLoader包括2个重载的loadClass类
- protected synchronized Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException
- public Class<?> loadClass(String name) throws ClassNotFoundException
两个方法都需要传name,既类的全限定名作为参数。
resolve:表示是否需要连接该类型。
注意:是连接(这里面包括校验class文件,准备分配内存,类型常量池的替换),并不会初始化该类型。
看源码可以看到,resolve也只是调用了一下resolveClass这个方法
- if (resolve) {
- resolveClass(c);
- }
都说清楚了,也很容易区分出不同点:
1.Class.forName返回的Class对象可以决定是否初始化。而ClassLoader.loadClass返回的类型绝对不会初始化,最多只会做连接操作。
2.Class.forName可以决定由哪个classLoader来请求这个类型。而ClassLoader.loadClass是用当前的classLoader去请求。
举个例子吧:
JDBC的注册驱动大家都狠熟悉吧:
- Class.forName(".......")
为啥是要用Class.forName?
首先看看注册驱动是什么意思。
打开DriverManager的代码,可以看到这个方法:
- public static synchronized void registerDriver(java.sql.Driver driver)
- throws SQLException
如果要注册驱动,必须得这么来
- DriverManager.registerDriver("......")
而这行代码,都是写在驱动的实现类,而且是一个static块来加载的。
所以随便找一个jdbc驱动程序的代码,肯定会有这样的实现
- static{
- .......
- DriverManager.registerDriver("......")
- .......
- }
用来注册驱动程序到DriverManager,这样驱动才能使用。
由于static块是属于类的,所以,此处仅仅需要初始化类即可。不需要具体实例。
那么用
- Class.forName(".....")
再合适不过了。
而ClassLoader由于不会初始化类。明显不行。
0 0
- Class.forName与ClassLoader(转)
- Class.forName与ClassLoader
- class.forname与classloader
- Class.forName与ClassLoader
- Class.forName与ClassLoader
- Class.forName()与ClassLoader.loadClass的区别(转)
- Class.forName与classLoader区别
- Class.forName()与ClassLoader.loadClass()的区别
- ClassLoader.loadClass()与Class.forName()的区别
- Class.forName与ClassLoader.loadClass的区别
- Class.forName()与ClassLoader.loadClass()的区别
- Class.forName与ClassLoader.loadClass的区别
- Class.forName()与ClassLoader.loadClass的区别
- Class.forName()与ClassLoader.loadClass()的区别
- 关于 ClassLoader.loadClass() 与 Class.forName() 关系
- Class.forName 和 classloader
- Class.forName()、ClassLoader.loadClass()
- ClassLoader和Class.forName
- 自定义toast
- LayerMask,Camera.cullingMask
- Spark Shuffle之Hash Shuffle
- 为什么tty0 没有输出?
- gccxml
- Class.forName与ClassLoader(转)
- 反记账对BSEG和FAGLFLEXA的影响
- 多线程同步方法
- thinkphp链接oracle
- Jenkins进阶系列之——01使用email-ext替换Jenkins的默认邮件通知
- Drupal 7 自定义页面如何向自定义的主题传参
- PullToRefreshListView不显示
- Android 中 PopupWindow 的用法
- UIAlertController 在didSelectRowAtIndexPath里 有时候点了半天才出来