当前位置: 首页 > 面试题库 >

Java ClassLoader是否加载内部类?

逑禄
2023-03-14
问题内容

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

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;
        }
    }

注意

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

这就是非静态内部类如何直接引用其父实例的字段和方法的方法,反之亦然。(在内部类中引用的父类的任何私有字段也都被设置为私有包。)

接下来,让我们看看加载类AA$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加载的所有类(见爪哇-
获取在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.Mainkuporific.A的加载时间,也看不到kuporific.A$Bkuporific.A$C正在加载。



 类似资料:
  • 如果我有一个内部类声明,例如: 其次是: A$B内部类也会加载吗?如果B内部类没有被声明为“静态”呢?

  • 我目前正在尝试将类加载到我的应用程序中,这样我就可以过滤掉那些不包含任何test/-方法的类。我希望以后在我的应用程序中运行这些测试。 到目前为止,一切都很好-除了我正在使用的(或者可能是任何)似乎没有实际重新加载位于我的应用程序类路径上的类。 更准确地说,我的应用程序的用户首先选择一些源文件。然后将它们复制到临时位置,并将许多正则表达式匹配/替换对应用于原始源文件的副本。接下来,拷贝被编译,然后

  • CLMAIN->clA(类A,$B)。$B是类a的内部类B。 从clMain创建具有指定url的新clA到包含类A(和类$B)的jar文件。然后通过CLA创建新对象A。 从X加载的另一个类通过接口执行对象a的方法没有问题。 然后,在该方法中,应该创建新对象$b,但它抛出. 在类A的构造函数中加载类$B可以解决以下问题:

  • 我在任何地方都找不到如何在RDD内部执行重新分区?我知道您可以在RDD上调用重新分区方法来增加分区数量,但它是如何在内部执行的呢? 假设,最初有5个分区,他们有- 第一个分区 - 100 个元素 第二个分区 - 200 个元素 第 3 个分区 - 500 个元素 第 4 个分区 - 5000 个元素 第 5 分区 - 200 个元素 一些分区是倾斜的,因为它们是从HBase加载的,并且数据没有正确

  • 问题内容: 我有一个动态网页,在这里我需要在另一个JavaScript文件中(在一定条件下)导入外部JS 文件。 我试图寻找可行的解决方案,但没有成功。 我尝试使用将JS文件加载到DOM,但也没有用。显然,Js已加载到DOM中,但在当前JS文件中无法访问。 jQuery中的解决方案也可以 问题答案: jQuery 有时会出现故障,因此我使用自己的实现方式: 并像这样使用它:

  • 问题内容: 我需要在我的站点中显示另一个外部站点的内容。通常标签可以做到这一点。但我的要求不是全部内容,而只是该网站的一部分。例如该网站的布局有3个部分,,,。我的意思是我只想显示一部分。我该怎么做? 我试过了,但是没有用。 问题答案: 这是由于ajax跨域安全性限制,一种技巧是从服务器设置代理脚本,该脚本从不同的站点(域)下载内容,并将该代理用作javascript中的参考。 示例:(proxy