`
terrine
  • 浏览: 840 次
文章分类
社区版块
存档分类
最新评论

Class loading之惑

阅读更多
    最近遇到一件怪事,打破了我多年来对java dynamic class loading习惯性的粗浅的认识……
    问题是这样,假设有一个class A,在它的某个方法test()中引用了class B, 如果A在运行的过程没有执行到test(),根据load class on demand的原理,B就不会没load。
代码如下:
java 代码
 
  1. public class A {  
  2.     public static void main(String[] args) {  
  3.         A a = new A();  
  4.         a.print(); 
  5.     }  
  6.      
  7.     public void print() {  
  8.         System.out.println("hello class loading");  
  9.     }  
  10.      
  11.     public void test(){  
  12.         B b = new B();  
  13.         b.smile();  
  14.     }  
  15.     
  16. }  
  17.   
  18. public class B {  
  19.     public void smile() {  
  20.         System.out.println(";-)");  
  21.     }  
  22. }  
   
    打开verbose选项可以看到B并不会被load,符合我们的习惯性认识。但是如果现在加入一个interface C,在test()方法中创建一个C的实例,并调用该实例的某个方法,就可以看到即使test()方法没有执行,C依然会被load到虚拟机中!
java 代码
 
  1. public class A {  
  2.     public static void main(String[] args) {  
  3.         A a = new A();  
  4.         a.print();  
  5.     }  
  6.       
  7.     public void print() {  
  8.         System.out.println("hello class loading");  
  9.     }  
  10.       
  11.     public void test(){  
  12.         B b = new B();  
  13.         b.smile();  
  14.         C c = new C() {  
  15.             public void cry() {  
  16.                 System.out.println("cry...");  
  17.             }  
  18.         };  
  19.         c.cry();  
  20.     }  
  21. }  
  22. public interface C {  
  23.     public void cry();  
  24. }  
   
摘一段执行的log:
……
[Loaded java.security.cert.Certificate from C:\jdk150_04_for_netbeans\jre\lib\rt.jar]
[Loaded A from file:/D:/eclipse-SDK-3.2-win32/workspace/cl/]
[Loaded C from file:/D:/eclipse-SDK-3.2-win32/workspace/cl/]
hello class loading
[Loaded java.lang.Shutdown from C:\jdk150_04_for_netbeans\jre\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\jdk150_04_for_netbeans\jre\lib\rt.jar]

    如果不用匿名类,而使用一个具体的C的实现CImpl,情况会略有不同:如果引用的是interface,即C c= new CImpl(); C依然会被load进来,如果引用是实现类,即CImpl c = new CImpl(); 则C和CImpl都不会被load。

    查了language spec也没有找到理论依据,那位给解释解释这是什么原因造成的?
分享到:
评论
7 楼 terrine 2007-01-28  
foxty,假设这里只有一句
C c = new CImpl();
并不使用变量c(c作为参数或者调用c的方法),可以看到C和CImpl都不会被装载进来。你所说的对字节码进行验证指的是什么呢?按照你之前的说法,这里依然用接口C引用了CImpl,C和CImpl就应该也被装载进来才对。
6 楼 foxty 2007-01-28  
terrine 写道
foxty 写道
应该是虚拟机进行字节码验证的时候对类型进行检查引起的。

如果用接口C引用CImpl,classloader应该会载入C和CImpl来检查C是否能够引用CImpl。

如果是用CImpl引用CImpl的话,就不需要载入来进行验证了。

这个是我推测的,不一定正确。
谢谢,但是我的问题是:为什么方法test()并没有被执行,接口C却被载入了呢?因为即使我使用匿名类,接口C依然会被载入进来。


虚拟机进行字节码验证的时候会对整个类的字节码进行验证,所以这里跟你执行不执行没有关系。
5 楼 shaucle 2007-01-27  
it's tricky, should avoid?
4 楼 山里有鬼 2007-01-26  
都是高手
3 楼 XMLDB 2007-01-26  
内部匿名类随类装载而装载,由于内部匿名类是继承法了接口C, 在装载过程中必须认识"C"才能装匿名类.
2 楼 terrine 2007-01-26  
foxty 写道
应该是虚拟机进行字节码验证的时候对类型进行检查引起的。

如果用接口C引用CImpl,classloader应该会载入C和CImpl来检查C是否能够引用CImpl。

如果是用CImpl引用CImpl的话,就不需要载入来进行验证了。

这个是我推测的,不一定正确。
谢谢,但是我的问题是:为什么方法test()并没有被执行,接口C却被载入了呢?因为即使我使用匿名类,接口C依然会被载入进来。
1 楼 foxty 2007-01-25  
应该是虚拟机进行字节码验证的时候对类型进行检查引起的。

如果用接口C引用CImpl,classloader应该会载入C和CImpl来检查C是否能够引用CImpl。

如果是用CImpl引用CImpl的话,就不需要载入来进行验证了。

这个是我推测的,不一定正确。

相关推荐

    powermock-classloading-xstream-1.4.7

    powermock-classloading-xstream-1.4.7powermock-classloading-xstream-1.4.7powermock-classloading-xstream-1.4.7powermock-classloading-xstream-1.4.7powermock-classloading-xstream-1.4.7powermock-class...

    org.springframework.instrument.classloading-3.0.0.M4

    org.springframework.instrument.classloading-3.0.0.M4.jar

    Dynamic loading class in the java virtual machine

    Dynamic loading class in the java virtual machine

    jcl.zip_Creating_class loading java_jcl

    It is the class responsible for finding and loading class files at run time. Creating your own ClassLoader lets you customize the JVM in useful and interesting ways, allowing you to completely ...

    Java Classloading Mechanism : ClassLoader & ASM & 动态字节码增强

    1. 加载(Loading):查找并读取类的二进制数据,通常是来自.class文件。 2. 验证(Verification):确保字节码符合Java语法规则且不会危害JVM的安全。 3. 准备(Preparation):为类的静态变量分配内存并初始化它们...

    Dynamic Class Loading in the Java Virtual Machine

    ### 动态类加载在Java虚拟机中的...动态类加载机制是Java平台的核心特性之一,它不仅增强了程序的灵活性和扩展性,还确保了类型安全。通过深入理解并合理利用这项技术,开发者可以构建出更加高效、可维护的应用系统。

    vue 全局封装loading加载教程(全局监听)

    前言: 为了页面美观,请求接口的时候延迟没有数据,页面感觉狠卡顿,封装... <div class=loading> 加载中... [removed] export default { props: {}, data() { return {}; }, computed: {}, created() {

    vue loading 页面加载动画提示

    <div class="loading-mask" v-if="isLoading"> <div class="loading-spinner"> <!-- 这里可以是SVG、CSS动画或者其他你喜欢的加载动画 --> export default { data() { return { isLoading: false } }...

    vue写的confirm确认框,loading加载中,message提示消息

    vue写的confirm确认框,loading加载中,message提示消息 在vue的模板里引用 import message from './tips/message/index'; import confirm from './tips/confirm/index'; import loading from './tips/loading/index...

    class-un-loading.tar.gz

    标题" class-un-loading.tar.gz "暗示了这个压缩包可能包含与Java类卸载相关的资料或工具。 Java虚拟机的设计中,类加载(Class Loading)是动态加载类到JVM的过程,而类卸载则是相反的操作,即从内存中移除不再...

    Lazy loading - eager loading

    In this article I want to discuss the lazy loading mechanism provided by NHibernate. It is recommended for maximum flexibility to define all relations in your domain as lazy loadable. This is the ...

    Error:scalac: missing or invalid dependency detected while loading class file ‘Tensor.class’.

    Error:scalac: missing or invalid dependency detected while loading class file 'Tensor.class'. Could not access term mllib in package org.apache.spark, because it (or its dependencies) are missing. ...

    安卓实现仿微信loading提示框

    对话框是一种轻量级的窗口,它可以浮现在应用程序主窗口之上,用于向用户显示临时信息或者进行简单的交互。在安卓中,我们可以使用`AlertDialog`或自定义`DialogFragment`来创建对话框。微信的Loading提示框通常由一...

    5个可爱的CSS3 Loading加载动画

    之前我们分享过很多漂亮的CSS3 Loading加载动画,印象最深的要算这款CSS3 Loading进度条加载动画特效 3款绚丽风格。这次要给大家介绍的是另外一款可爱的CSS3 Loading动画,一共有5种动画类型,每组Loading动画都非常...

    ClassFinal是一款java class文件安全加密工具

    ClassFinal正是为解决这些问题而设计的一款Java类文件安全加密工具。这款工具能够对编译后的`.class`文件进行加密处理,使得未经授权的用户无法轻易读取或反编译代码,从而提高代码的安全性。 ClassFinal的特点在于...

    powermock-classloading-xstream-1.4.8.jar

    最底一分,xstream-1.4.8的jar包、源码、说明文档.zip

    javascript实现一个网页加载进度loading

    <div class="loading" id="loading"> <div class="progress" id="progress">0% ``` 接着,添加 CSS 样式来美化 loading 元素: ```css .loading { display: table; position: fixed; top: 0; left: 0; ...

    jQuery SVG实现Loading加载按钮动画图标特效.zip

    <button class="loading-button circular-loading top">Send <button class="control-button bordered make-it-succeed">Make it succeed <div class="loading-options"> <div class="loaders"> <h2>Loaders ...

    css代码实现loading动画

    <div class="loading-spinner"> ``` 在这个例子中,我们创建了一个旋转的加载动画。`@keyframes loading`定义了从0%到100%的动画过程,元素从0度旋转到360度。`.loading-spinner`是承载动画的元素,设置为圆形,...

    兼容性良好的css3点点点loading动画提交效果.zip

    <div class="dot loading-dot-1"> <div class="dot loading-dot-2"> <div class="dot loading-dot-3"> ``` 每个`.loading-dot`类的元素代表一个点,通过CSS控制它们的样式和动画。 **兼容性考虑** 为了确保这...

Global site tag (gtag.js) - Google Analytics