【问题标题】:Unwanted import added by compiler [duplicate]编译器添加了不需要的导入[重复]
【发布时间】:2021-11-27 19:38:21
【问题描述】:

我需要相同的代码在具有不同库的不同服务器上工作。

例如 serverB 包含 libraryB。 ClassB 而 serverA 没有。

为了使代码在两台服务器上都能正常工作,我没有显式导入该类,而是仅在需要时声明它。例如:

If(serverB) {
   libraryB.ClassB foo = new libraryB. ClassB();

   foo.doSomething();
}else{
   whatever();
}

这通常对我有用,但现在我在新服务器上安装了我的代码,我得到了 NoClassFoundException。我反编译了我的类并导入了库。为什么?我可以避免吗?

谢谢

【问题讨论】:

  • 您能否定义接口并根据您是在服务器 B 还是服务器 A 上使用正确的类/类型注入特定的实现?
  • 导入只是语法糖。无论您是否使用其完全限定名称导入某些内容,都没有区别。
  • 您确定“is server B”逻辑工作正常吗?

标签: java noclassdeffounderror javacompiler javaimports


【解决方案1】:

从包中导入某些类与在运行时尝试定位该类无关。每当 JVM 检测到需要像 ClassB 这样的类时,它就会尝试定位并加载该类。

何时发生这种情况的确切说明有些复杂,但是无论您编写完全限定的libraryB.ClassB 还是缩写的ClassB 和导入语句都没有区别。并且定位该类肯定会在 JVM 甚至尝试执行包含对该类的引用的代码之前发生(例如您向我们展示的代码 sn-p)。

不要被包含import 语句的反编译误导。您可以自己尝试并比较您的代码的两个版本,一个使用 import 编写,另一个使用完全限定的类名。结果将是相同的。这只是为了方便反编译器优先使用短类名,因此它总是添加相关的导入语句(只要不会导致名称冲突)。

很难理解为什么像你这样的代码运行时没有抛出错误。

【讨论】:

  • 好的,非常感谢。所以你说应该不可能在两台安装了不同库的机器上运行代码,对吧?
  • 是的。如果它是完全相同的编译二进制类文件,我无法理解这部分代码如何在没有ClassB 可用的机器上执行(即使执行总是采用else 路径)。作为执行方法的先决条件,该类必须已被 JVM 完全链接,如果缺少引用的类,则会引发错误。
  • 我发现了一个类似的线程stackoverflow.com/questions/34259275/…。这里有人说它可能取决于 JVM 以及如何调用该类。
猜你喜欢
  • 2014-10-22
  • 2019-10-18
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多