ClassLoader和ClassForname的区别(详解)
一、概述
1.clssLoader和classForName都是用来加载类的,但是这两个方法一般却又在不同的场景使用。
如classLoader一般是spring容器用来加载bean的时候使用的,而classForName一般我们都是在使用数据库驱动的时候会使用该方法。
2.了解了两个加载类的不同场景之外后,先看一下类加载的过程。
2.1 .class文件首先被加载到jvm中
2.2然后经过链接,在链接中有3个步骤。
首先验证:验证是为了保证我们的.class文件的合法性。会分别尽心文件格式验证,元数据验证,字节码验证,符号引用验证
然后准备:初始化静态成员变量,并赋值
最后解析:将符号引用转换为直接引用
2.3初始化,执行静态代码快。类装载过程到此结束
二、两个方法的底层实现
1.classForname
public static Class<?> forName(String className) throws ClassNotFoundException {return forName0(className, true, ClassLoader.getCallerClassLoader());}
接着看forName0这个方法
/** Called after security checks have been made. */private static native Class forName0(String name, boolean initialize,ClassLoader loader)throws ClassNotFoundException;
这里第二个参数initaline表示是否对加载的类进行初始化。
而我们的classforname传入的是true。所以classforname会对类进行初始化操作.
2.classloader
public Class<?> loadClass(String name) throws ClassNotFoundException {return loadClass(name, false);}
继续进入loadClass中
** @param name* The <a href="#name">binary name</a> of the class** @param resolve* If <tt>true</tt> then resolve the class** @return The resulting <tt>Class</tt> object** @throws ClassNotFoundException* If the class could not be found*/protected synchronized Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{// First, check if the class has already been loadedClass c = findLoadedClass(name);if (c == null) {try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.c = findClass(name);}}if (resolve) {resolveClass(c);}return c;}
* @param resolve
* If <tt>true</tt> then resolve the class
如果为true,则初始化类。
而在原代码中return loadClass(name, false);传入的是false,所以loaderClass则对类不进行初始化。
三、验证
1.两者的区别在在于一个会初始化操作,一个不会初始化操作,而在类加载过程中,初始化的作用主要是执行静态代码块。
体现在具体的代码中。
自定义一个类
package com.load;public class StringUtil {private static String name="小明";static{name="小哈";System.out.println("我是静态代码块");}public static void say(){System.out.println("我是:"+name);}
}
主函数
package com.load;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class Test {public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {Class.forName("com.load.StringUtil");System.out.println("classForname结束!");ClassLoader loader=Test.class.getClassLoader();Class<?> cl=loader.loadClass("com.load.StringUtil");System.out.println("类装载结束!!!!");Method me=cl.getMethod("say", null);me.invoke(cl, null);}
}
结果:
我是静态代码块
classForname结束!
类装载结束!!!!
我是:小哈
通过结果进行分析classform在之前便执行了静态代码块,而我们的loaderclass这个方法并没有执行静态代码块,只有在后面使用类的时候才执行了。
获取更多学习资料,面试题以及视频,关注微信公众号:
ClassLoader和ClassForname的区别(详解)相关推荐
- HashTable和HashMap的区别详解
HashTable和HashMap的区别详解 一.HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同 ...
- java mod %区别_Java中 % 与Math.floorMod() 区别详解
%为取余(rem),Math.floorMod()为取模(mod) 取余取模有什么区别呢? 对于整型数a,b来说,取模运算或者取余运算的方法都是: 1.求 整数商: c = a/b; 2.计算模或者余 ...
- 关于numpy中eye和identity的区别详解
https://www.jb51.net/article/175386.htm np.identity(n, dtype=None) np.eye(N, M=None, k=0, dtype=< ...
- php为什么需要配置路由器,laravel 配置路由 api和web定义的路由的区别详解
1.路由经过中间件方面不同 打开kerenl.php就可以看到区别 protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware ...
- python协程详解_对Python协程之异步同步的区别详解
一下代码通过协程.多线程.多进程的方式,运行代码展示异步与同步的区别. import gevent import threading import multiprocessing # 这里展示同步和异 ...
- Jar/War/Ear等包的作用与区别详解
Jar/War/Ear等包的作用与区别详解 以客户角度来看,jar文件就是一种封装格式,用户不需要知道jar包中有多少个.class格式的文件及每个文件中的功能与作用,也可以得到相应的访问的结果.ja ...
- Java中print、printf、println的区别 详解
Java中print.printf.println的区别详解 printf主要是继承了C语言的printf的一些特性,可以进行格式化输出 print就是一般的标准输出,但是不换行 println和pr ...
- axios请求接口http_使用axios请求接口,几种content-type的区别详解
axios的使用 安装(一般使用框架的话, 脚手架都集成了) $ npm install axios 请求示例 // POST axios.post('/user', { firstName: 'Fr ...
- vue 事件调用 传参_对vue下点击事件传参和不传参的区别详解
如下所示: {{btn_text1}} {{btn_text2}} var _vm = new Vue({ data : { btn_text1 : '点击1' , btn_text2 : '点击2' ...
- 17个之多!Windows Vista各版本功能区别详解
Vista 开始全球同步上市,版本达17个之多. Windows Vista各版本功能区别详解 : http://digi.it.sohu.com/2006 ...
最新文章
- android用于打开各种文件的intent
- div中的图像在图像下方有多余的空间
- 详解linux系列之sendmail邮箱服务的安装及配置
- Xcode7常见问题汇总
- Java 集合 List Arrays.asList
- python re 匹配多行_Python正则表达式,看这一篇就够了
- 谷歌推出开源工具DeepVariant,用深度学习识别基因变异
- android 中 FLAG_SHOW_WHEN_LOCKED 的用法及解释
- charles抓手机app的包的操作步骤
- Eclipse 中如何设置字体大小与样式
- 漏洞补丁在线更新失败或软件安装提示ERROR的解决方案
- Hadoop原理及架构
- C# winform 魔兽MH全图制作教程(3):魔兽1.20E.1.24B.1.24E全图内存地址 转自breeze...
- datetime instant 转_java8 Instant 时间及转换操作
- JavaWeb-过滤器Filter学习(三)实现用户的自动登录与IP黑名单过滤
- HTML5高级之position(定位)
- 教养,就是要让别人舒服
- 哈工大计算机网络-作业讲解
- 在云计算大数据学习中心学习的第一天
- 痞子衡嵌入式:超级下载算法RT-UFL v1.0发布,附J-Link下安装教程