如果我有一个内部类声明,例如:
Class A {
public static class B {
}
}
接着是:
Class<?> implClass = getClass().getClassLoader().loadClass("A");
A$B 内部类也会被加载吗? 如果 B 内部类没有声明为“静态”呢?
最佳答案
一旦代码被编译,就没有内部类这种东西了。如果你查看 javac
的结果,你会看到两个文件:
A.class
A$B.class
所以类B
在A
被加载的时候并没有被加载,B
只是发生被定义在A
.
编辑
例如,给定这两个文件,
package kuporific;
public class A {
private static class B {}
private class C {}
}
和一个 build.gradle
文件(为方便起见):
apply plugin: 'java'
首先,通过运行 gradle build
进行构建。然后,解压缩生成的 JAR 文件(位于 build/libs
中):
├── META-INF
│ └── MANIFEST.MF
└── kuporific
├── A$B.class
├── A$C.class
└── A.class
打开每个文件(例如在 IntelliJ 中),显示编译器做了什么:
A.class
:package kuporific; public class A { public A() { } private class C { public C() { } } private static class B { public B() { } } }
A$B.class
:package kuporific; class A$B { private A$B() { } }
A$C.class
:package kuporific; import kuporific.A; class A$C { private A$C(A this$0) { this.this$0 = this$0; } }
注意
A$B
没有对其父级A
的引用,而A$C
有。这是因为前者是静态内部类,而后者不是,并且A$B
和A$C
现在都是 package private 类。
这就是非静态内部类能够直接引用其父实例的字段和方法的方式,反之亦然。 (内部类中引用的父类的任何私有(private)字段也被设为包私有(private)。)
接下来我们看看加载类A
对A$B
和A$C
有什么影响。
首先,添加以下 Java 类:
package kuporific;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Main.class.getClassLoader().loadClass("kuporific.A");
}
}
现在将以下内容添加到 build.gradle
文件中:
apply plugin: 'application'
mainClassName = 'kuporific.Main'
applicationDefaultJvmArgs = ["-verbose:class"]
-verbose:class
输出 JVM 加载的所有类(参见 Java - Get a list of all Classes loaded in the JVM)。
在命令行运行gradle run
(运行Main
的main
方法);输出(带有我添加的注释)是
:compileJava
:processResources UP-TO-DATE
:classes
:run
[Opened /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded java.lang.Object from /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar]
# Lots of omitted output...
[Loaded kuporific.Main from file:/tmp/build/classes/main/]
^ here!
[Loaded sun.launcher.LauncherHelper$FXHelper from /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded java.lang.Class$MethodArray from /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded kuporific.A from file:/tmp/build/classes/main/]
^ here!
[Loaded java.lang.Shutdown from /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded java.lang.Shutdown$Lock from /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar]
BUILD SUCCESSFUL
Total time: 6.502 secs
我们可以看到 kuporific.Main
和 kuporific.A
的加载时间,但我们看不到 kuporific.A$B
或kuporific.A$C
正在加载中。
关于java - Java ClassLoader 是否加载内部类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24538509/