(转)classload和class.forname()区别
2015-09-20 11:47
323 查看
转自:http://carl-java.iteye.com/blog/978680
java中class.forName和classLoader都可用来对类进行加载。前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象
事例代码如下:
1.使用classLoader加载
System.out.println("before loadClass... ");
Class c =Test.class.getClassLoader().loadClass("com.hundsun.test.ClassInfo");
System.out.println("after loadClass... ");
System.out.println("before newInstance... ");
ClassInfo info1 =(ClassInfo) c.newInstance();
System.out.println("after newInstance... ");
输出结果:
before loadClass...
after loadClass...
before newInstance...
static invoked...
contruct invoked...
after newInstance...
2.使用class.forName进行加载
System.out.println("before class.forName");
Class cc =Class.forName("com.hundsun.test.ClassInfo");
System.out.println("after class.forName");
ClassInfo info2 =(ClassInfo) cc.newInstance();
输出结果:
before class.forName
static invoked...
after class.forName
before newInstance...
contruct invoked...
after newInstance...
下面说一下两者具体的执行过程
LoadClass()方法加载类及初始化过程:
类加载(loadclass())(加载)——》newInstance()(链接+初始化)
newInstance():
(开始连接)静态代码块——》普通变量分配准备(a=0;b=0;c=null)——》(开始初始化)普通变量赋值(a=1;b=2;c=”haha”)——》构造方法——》初始化成功。
Class.forName(Stirng className)一个参数方法加载类及初始化过程:
类加载(Class.forName())(加载)——》静态代码块——》newInstance()(链接+初始化)
newInstance():
(开始连接)普通变量分配准备(a=0;b=0;c=null)——》(开始初始化)普通变量赋值(a=1;b=2;c=”haha”)——》构造方法——》初始化成功。
Class.forName()三个参数的加载类及初始化过程同classLoader一样。
从上边的断点调试可以看出,静态代码块不是在初始化阶段完成的,它陷于类初始化,先于普通变量默认分配(整型分配为0,字符串分配为null),这也就是为什么我们不能在静态代码块中引用普通变量的原因之一,这与上面所谓的“分配”、“初始化”相违背。
所以我觉得JVM的类加载及初始化过程应该是这样的。
1. 类加载:Bootstrap Loader——》Extended Loader——》System Loader
2. 静态代码块初始化
3. 链接:
a) 验证:是否符合java规范
b) 准备:默认初始值
c) 解析:符号引用转为直接引用,解析地址
4. 初始化
a) 赋值:java代码中的初始值
b) 构造:构造函数
java中class.forName和classLoader都可用来对类进行加载。前者除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。而classLoader只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象
事例代码如下:
1.使用classLoader加载
System.out.println("before loadClass... ");
Class c =Test.class.getClassLoader().loadClass("com.hundsun.test.ClassInfo");
System.out.println("after loadClass... ");
System.out.println("before newInstance... ");
ClassInfo info1 =(ClassInfo) c.newInstance();
System.out.println("after newInstance... ");
输出结果:
before loadClass...
after loadClass...
before newInstance...
static invoked...
contruct invoked...
after newInstance...
2.使用class.forName进行加载
System.out.println("before class.forName");
Class cc =Class.forName("com.hundsun.test.ClassInfo");
System.out.println("after class.forName");
ClassInfo info2 =(ClassInfo) cc.newInstance();
输出结果:
before class.forName
static invoked...
after class.forName
before newInstance...
contruct invoked...
after newInstance...
下面说一下两者具体的执行过程
LoadClass()方法加载类及初始化过程:
类加载(loadclass())(加载)——》newInstance()(链接+初始化)
newInstance():
(开始连接)静态代码块——》普通变量分配准备(a=0;b=0;c=null)——》(开始初始化)普通变量赋值(a=1;b=2;c=”haha”)——》构造方法——》初始化成功。
Class.forName(Stirng className)一个参数方法加载类及初始化过程:
类加载(Class.forName())(加载)——》静态代码块——》newInstance()(链接+初始化)
newInstance():
(开始连接)普通变量分配准备(a=0;b=0;c=null)——》(开始初始化)普通变量赋值(a=1;b=2;c=”haha”)——》构造方法——》初始化成功。
Class.forName()三个参数的加载类及初始化过程同classLoader一样。
从上边的断点调试可以看出,静态代码块不是在初始化阶段完成的,它陷于类初始化,先于普通变量默认分配(整型分配为0,字符串分配为null),这也就是为什么我们不能在静态代码块中引用普通变量的原因之一,这与上面所谓的“分配”、“初始化”相违背。
所以我觉得JVM的类加载及初始化过程应该是这样的。
1. 类加载:Bootstrap Loader——》Extended Loader——》System Loader
2. 静态代码块初始化
3. 链接:
a) 验证:是否符合java规范
b) 准备:默认初始值
c) 解析:符号引用转为直接引用,解析地址
4. 初始化
a) 赋值:java代码中的初始值
b) 构造:构造函数
相关文章推荐
- 统计学分成绩
- 算法
- static静态变量的理解
- hdoj 1102 Constructing Roads 【最小生成树&&prim】
- DOTNET笔记_值比较的实现
- iptables详解
- Android 利用addView 动态给Activity添加View组件
- 大道至简第一章感想
- UIMenuController的使用,对UILabel拷贝以及定制菜单
- 概要设计说明书——机房收费系统
- Runnable接口与Thread类的区别
- 【图像处理笔记】平滑空间滤波器
- NSMutableArray的基本使用
- google protocol buffer -2-.proto 定义规则
- 第三周项目一 顺序表的基本运算(1)
- java单例模式
- 上帝给谁的都不会太多
- 面试中常问的关于链表的题目
- Google Protocol Buffer 的使用和原理
- ASP.NET大文件上传方案