当前位置: 首页 > 知识库问答 >
问题:

java类是如何加载的,我如何知道一个类在哪里/什么时候/为什么被加载?

邴俊友
2023-03-14

所以我有点理解java类加载器是什么,因为它为JVM准备编译的.class文件。我几乎不理解它是如何工作的,因为它试图通过一系列递归调用父类加载器的步骤来加载一个类。我没有理解的是类加载器是如何确定的。也就是说,如何为类选择类加载器?

我现在问这个问题是因为我基本上遇到了以下问题:我无法将子类强制转换到实现的接口。

该类如下所示:

html" target="_blank">public class AccountBoImpl implements AccountBo {
...
}

这是我的(略经编辑的)stacktraces的结尾:

15:49:47.269 [DefaultThreadPool-7] ERROR com.company.app.kem.biz.ao - 
java.lang.ClassCastException: com.company.app.department.bo.AccountBoImpl cannot be cast to com.company.domain.core.biz.AccountBo
    at com.company.domain.core.biz.AccountBOF.findBySomething(AccountBOF.java:62) ~[Client-1.0.0-SNAPSHOT.jar:na]
    at com.company.domain.shared.biz.applogic.balances.SiteAccountBalanceProcessor.setUnbilledUsage(SiteAccountBalanceProcessor.java:347) ~[Domain-1.0.0-SNAPSHOT.jar:na]

这里,AccountBoImpl和AccountBo(AccountBoImpl实现的接口)之间的包是不同的。我想知道是什么决定了这些类的加载方式。比如为什么我导入com . company . app . billing . bo . AccountBo的时候,account bo是和com.company.domain.core.biz包一起加载的;?我知道在这段代码中的某个地方,会调用一个模块类来初始化这些类。但是我不确定在这个模块课上要找什么。

最后,为了弄清楚为什么这个类被错误地加载,我假设我需要找出它加载的位置/时间。但是我该怎么做呢?我只知道类是根据需要加载的(无论这真正意味着什么),但我不知道我该如何解决这个问题。例如,对于变量,我可以调试/单步执行代码以查看何时分配变量值。但是对于一个班级来说...?我在寻找什么?我知道在这个代码库中,我们有遗留代码,它提供了许多与新代码相同的类,但是我如何使用这些信息来解决我的问题?

如果我遗漏了关键信息或者这个问题看起来含糊不清,我事先道歉。我不知道如何解决这个问题,因为我刚刚得知ClassLoaders昨天就存在了。

共有1个答案

公西翊歌
2023-03-14

如何解析简单名称< code>AccountBo的决定是在编译时做出的。

如果您确实有< code > import com . company . app . billing . bo . account bo;语句,不可能将< code>implements AccountBo子句解析为不同包的类。

ClassCastException正是承认了这一点,因为它说您的类不能分配给com.company.domain.core.biz.AccountBo

因此,类装入器没有问题,错误解析的标识符也没有问题。您的类实现了 com.company.app.billing.bo.AccountBo,但在方法 findBySomething 中,类 com.company.domain.core.biz.AccountBOF 尝试将类的实例投射到 com.company.domain.core.biz.AccountBo,但它不会实现。

一般来说,有这样容易混淆的名字的公开课不是一个好主意。

 类似资料:
  • 问题内容: 我们正在创建多个子类加载器,以将多个子应用程序加载到Java应用程序“容器”中,从而对热部署进行原型设计。当特定类加载器的类路径发生更改时(即,添加,删除,更新了jar),旧的类加载器将被丢弃(未引用),并为jar的新类路径创建新的类加载器。 更新类路径后,触发热部署,我们进行了堆转储。堆转储(使用内存分析器)表明旧的类加载器未在进行垃圾回收。父类加载器中的某些类正在缓存旧的类加载器。

  • 问题内容: 我在其他地方找不到这个问题的明确答案,因此我将在这里尝试: 是否有某种方法(以编程方式或其他方式)来获取Application Classloader加载时所加载的JAR /类列表的确切顺序?应用程序类加载器,我是指在应用程序服务器(WLS,WAS,JBoss …)中加载EAR应用程序的类加载器,但显然,它适用于任何类加载器。 因此,概括地说,我想找出的是由指定类加载器加载的JAR的列

  • 问题内容: 我们知道我们可以使用以下方法覆盖System 类加载器: 那么,既然它本身是一个类,它是由谁加载的? 我们如何获得该“元”类加载器的类文件? 问题答案: 从Javadoc中获取: 如果在首次调用此方法时定义了系统属性“ java.system.class.loader”,则该属性的值将作为要作为系统类加载器返回的类的名称。 该类使用默认的系统类加载器加载, 并且必须定义一个公共构造函数

  • 文档中的这段代码完全让我感到困惑: 我明白了,摩基托很奇怪而且几乎不在Java。令人困惑的是必须充分评估才能知道它是否被包装在或其他文件中。第一个方法为什么不调用实际对象,而后面的方法却调用了?

  • 问题内容: 该ProGuard的主页上列出的功能: 重新定位和预先验证Java 6的现有类文件,以充分利用Java 6更快的类加载速度。 它所指的Java 6有什么区别? 重要吗? 它会对通过默认类加载器的同步方面的多线程导致的速度下降产生影响吗? 问题答案: 如ProGuard 常见问题解答所提示: Java 6编译器将预验证信息添加到类文件中 查看“ 按类型检查的Java虚拟机规范 验证”部分

  • JVM类加载机制主要有三种: 1、全盘负责 类加载器加载某个class时,该class所依赖的和引用其它的class也由该类加载器载入。 2、双亲委派 先让父加载器加载该class,父加载器无法加载时才考虑自己加载。 3、缓存机制 缓存机制保证所有加载过的class都会被缓存,当程序中需要某个class时,先从缓存区中搜索,如果不存在,才会读取该类对应的二进制数据,并将其转换成class对象,存入