Java ClassLoader是否加载内部类?

Jan*_*sky 22 java classloader

如果我有一个内部类声明,例如:

Class A {
    public static class B {
    }
}
Run Code Online (Sandbox Code Playgroud)

其次是:

Class<?> implClass = getClass().getClassLoader().loadClass("A");
Run Code Online (Sandbox Code Playgroud)

A $ B内部类也会被加载吗?如果B内部类没有被声明为"静态"怎么办?

kup*_*fic 29

编译代码后,就没有内部类.如果你查看结果javac,你会看到两个文件:

A.class
A$B.class
Run Code Online (Sandbox Code Playgroud)

因此B加载时不会加载类A,B只是恰好定义了A.


编辑

例如,给定这两个文件,

package kuporific;

public class A {
    private static class B {}
    private class C {}
}
Run Code Online (Sandbox Code Playgroud)

build.gradle文件(为方便起见):

apply plugin: 'java'
Run Code Online (Sandbox Code Playgroud)

首先,通过运行构建gradle build.然后,解压缩生成的JAR文件(位于build/libs):

??? META-INF
?   ??? MANIFEST.MF
??? kuporific
    ??? A$B.class
    ??? A$C.class
    ??? A.class
Run Code Online (Sandbox Code Playgroud)

打开每个文件(例如,在IntelliJ中),显示编译器已完成的操作:

请注意

  1. A$B没有其父的引用,AA$C做.这是因为前者是静态内部类,而后者不是,而且
  2. 这两个A$BA$C现在包专用类.

这就是非静态内部类能够直接引用其父实例的字段和方法的方式,反之亦然.(内部类中引用的父类的任何私有字段也都是私有的.)

接下来,让我们来看看装载类什么样的影响A,对A$BA$C.

首先,添加以下Java类:

package kuporific;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        Main.class.getClassLoader().loadClass("kuporific.A");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在将以下内容添加到build.gradle文件中:

apply plugin: 'application'
mainClassName = 'kuporific.Main'
applicationDefaultJvmArgs = ["-verbose:class"]
Run Code Online (Sandbox Code Playgroud)

-verbose:class输出由JVM加载的所有类(见爪哇-获取在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
Run Code Online (Sandbox Code Playgroud)

我们可以看到,当kuporific.Mainkuporific.A加载,我们没有看到任何kuporific.A$Bkuporific.A$C加载.