java classes 是如何加载的,我如何计算出 where/when/why a class 已加载?

How are java classes loaded and how do I figure out where/when/why a class is loaded?

所以我有点理解什么是 java 类加载器 is in that it prepares compiled .class files for the JVM. I just barely understand how it works,因为它试图通过一系列递归调用父类加载器的步骤来加载 class。我不明白的是如何确定 ClassLoader。也就是说,如何为 class 选择 ClassLoader?

我现在问这个问题是因为我基本上 运行 遇到了以下问题:I can't cast a child class to the implemented interface

class 如下所示:

public class AccountBoImpl implements AccountBo {
...
}

这是我的(稍微编辑过的)堆栈跟踪的结尾:

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实现的接口)的包是不一样的。我想知道是什么决定了这些 classes 是如何加载的。例如,为什么当我导入 com.company.[=40= 时,AccountBo 加载了 com.company.domain.core.biz 包];?我知道在这段代码中的某个时刻,一个模块 class 被调用,它应该初始化 classes。但我不确定要在这个模块中寻找什么 class。

最后,要弄清楚为什么 class 加载不正确,我想我需要找出 where/when 它正在加载。但是我该怎么做呢?我只知道 classes 是根据需要加载的(不管这到底意味着什么),但我不知道我将如何解决这个问题。例如,对于一个变量,我可以 debug/step 进入代码以查看何时分配变量值。但是对于 class...?我在找什么?我知道在这个代码库中,我们有旧代码提供了许多与新代码相同的 classes,但是我如何使用这些信息来解决我的问题?

如果我遗漏了关键信息或者这个问题看起来含糊不清,我提前道歉。我不确定如何解决这个问题,因为我昨天才知道 ClassLoaders 存在。

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

如果您确实有一个 import com.company.app.billing.bo.AccountBo; 声明您的 class,implements AccountBo 子句不可能解析为不同包的 class。

并且 ClassCastException 准确地承认,正如它所说的那样,您的 class 不能 分配给 com.company.domain.core.biz.AccountBo

所以 class 加载程序没有问题,错误解析的标识符也没有问题。您的 class 实现了 com.company.app.billing.bo.AccountBo,但在 class 的方法 findBySomethingcom.company.domain.core.biz.AccountBOF 试图将您的 class 的实例转换为 com.company.domain.core.biz.AccountBo 它没有实现。

一般来说,让 public class 具有如此容易混淆的名称并不是一个好主意。