我试图理解为什么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决定加载类的原因吗?
答案 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是顶级类,则执行词法中嵌套在类中的断言语句。