为什么Java ClassLoader正在加载此类

时间:2016-09-16 05:39:53

标签: java classloader

我试图理解为什么JVM决定在它看起来不需要时加载某些类。请考虑以下示例代码:

<ul>
    <li>
        <p>Hello World</p>
    </li>
</ul>

调用/ul/.../p时,类加载器不会加载public class Foo { public void foo() { } static class Bar { } public Bar bar() { return new Bar(); } } ,因为它不需要。但是,如果我们更改示例以使new Foo().foo()返回子类的实例:

Bar

调用bar会导致类加载器加载public class Foo { public void foo() { } static class Bar { } static class BigBar extends Bar { } public Bar bar() { return new BigBar(); } } new Foo().foo()类,即使它们都不需要。为什么呢?

除了这个特定的场景之外,还有一种方法可以了解JVM决定加载类的原因吗?

2 个答案:

答案 0 :(得分:1)

以下是Internals of Java Class Loading

的精彩读物
  

每当通过输入java MyMainClass启动新的JVM时,   “bootstrap class loader”负责加载关键的Java类   像java.lang.Object和其他运行时代码首先进入内存。该   运行时类打包在JRE \ lib \ rt.jar文件中。我们   无法在Java中找到bootstrap类加载器的详细信息   文档,因为这是一个本机实现。对于相同的   原因,bootstrap类加载器的行为也会有所不同   跨越JVM。

     

在相关的说明中,如果我们尝试获取类加载器,我们将得到null   一个核心Java运行时类,如下所示:

log(java.lang.String.class.getClassLoader());
     

接下来是Java扩展类加载器。我们可以存储扩展   库,提供超出核心Java的功能的库   运行时代码,在java.ext.dirs属性给出的路径中。该   ExtClassLoader负责加载保存在的所有.jar文件   java.ext.dirs路径。开发人员可以添加自己的应用程序   .jar文件或他或她可能需要添加到的任何库   classpath到这个扩展目录,以便它们将被加载   扩展类加载器。

     

开发人员的第三个也是最重要的类加载器   透视是AppClassLoader。应用程序类加载器是   负责加载保存在路径中的所有类   对应于java.class.path系统属性。

答案 1 :(得分:0)

很好地解释了http://javarevisited.blogspot.in/2012/07/when-class-loading-initialization-java-example.html

在Java中加载Class时 类加载由Java中的ClassLoaders完成,只要另一个类引用它或者延迟加载类直到需要进行类初始化,就可以实现类加载类。如果Class在实际使用之前加载,它可以在初始化之前就位于内部。我相信这可能会有所不同,从JVM到JVM。虽然JLS保证在需要静态初始化时会加载一个类。 在Java中初始化类时 1)使用new()关键字或使用class.forName()的反射创建类的实例,这可能会在Java中抛出ClassNotFoundException。

2)调用Class的静态方法。 3)分配类的静态字段。 4)使用类的静态字段,它不是常量变量。 5)如果Class是顶级类,则执行词法中嵌套在类中的断言语句。