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) 构造:构造函数
- 浏览: 122081 次
- 性别:
- 来自: 洛阳
-
最新评论
-
xiayuhe1:
...
搜狗微信搜索获取文章点赞数和阅读数等 -
q474420502:
已经不行了
搜狗微信搜索获取文章点赞数和阅读数等 -
刘亮love小雪:
不错,非常好,我重新认识了闭包
JS闭包 -
cuippan:
为什么要用 两个 encodeURI
JS通过URL传递中文参数时出现乱码的处理 -
kingsmalltwo:
UUID唯一标识。
Java的MD5、SHA-1加密
相关推荐
8. **Class.forName与ClassLoader**:`Class.forName()`是静态方法,通过类名加载类;ClassLoader是动态加载类的机制,可以自定义加载策略。 9. **动态代理**:Java提供了JDK动态代理和CGLIB两种实现,前者基于接口...
`findClass()`方法用于加载类的字节码数据。 #### 动态代理 **JDK动态代理**: 1. **代理原理**:JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。通过实现`...
Class<?> clazz = Class.forName("Data"); Constructor<?> constructor = clazz.getConstructor(); Data data = (Data) constructor.newInstance(); Method method = clazz.getMethod("getData"); System.out....
- **通过类的加载器获取**:`Class.forName()`, `ClassLoader.loadClass()`. - **通过实例对象获取**:`instance.getClass()`. - **通过类名获取**:`SomeClass.class`. #### 22. 如何唤起类中的一个方法? 可以...
27. **Class.forName(String className)这个方法的作用** - 加载指定名称的类,并返回对应的Class对象。 28. **int和Integer的区别** - `int`是基本数据类型,`Integer`是`int`的包装类。 29. **位运算** - 位...
15.1.2 使用class.forname() 502 15.1.3 从class获得信息 503 15.1.4 从class建立对象 506 15.1.5 操作对象方法与成员 509 15.1.6 动态代理 512 15.2 了解类加载器 515 15.2.1 类加载器层级架构 515 ...
【反射】反射中,Class.forName和classloader的区别 42 【JVM】JAVA编译原理和JVM原理 42 【JVM】Java内存模型 44 【JVM】jvm内存模型 45 主内存与工作内存 45 内存间交互操作 46 重排序 48 【JVM】内存泄漏 49 ...
- **定义**: 负责加载应用程序类路径中的类。 **7.25 全盘负责委托机制** - **说明**: 类加载器之间的层次结构及委托关系。 #### XML 处理技术 **7.26 Tip:DTD 的语法细节** - **内容**: - 元素定义 - 属性定义...