0

我在我继承的一些代码中看到了一个有趣的行为,其中有一个带有依赖项 jar 的项目,其中存在一个与项目中的类具有相同名称和相同包的类:

日食项目:

src/com.abc.dE

取决于存在com.abc.dEclass的XYZ.jar

只是好奇这个设置在 Java 中是否合法。根据 Eclipse,它不会将其标记为错误并允许创建一个新类来隐藏依赖项 jar 中的现有类,除非尝试在工作区中重命名此类现有类 - 然后它会产生以下警告:

“已找到对重构元素的二进制引用。它们不会更新,如果继续,可能会导致问题。”

然后允许这种前向重构。但是,如果想向后重构一个冲突的名称,Eclipse 中会出现以下消息:

“名为 'E' 的类型已存在于包 'com.abc.d' 中

是这样吗

  • 一个正确的 Java
  • Eclipse 行为中允许的不一致或
  • .一个 Eclipse 错误?

谢谢你。

4

2 回答 2

1

如果两个类都可以被同一个类加载器访问(例如,如果两个 jar 文件发现自己在同一个类路径上),那么只会加载其中一个(可能是列表中的第一个),这将导致各种令人讨厌的结果,尤其是如果它们的行为不同。

假设库 1 使用E.frobnicate(),而库 2 期望有一个E.frob()方法:其中一个会得到 aNoSuchMethodError并且通常会失败。

一般来说,包名和类名应该唯一标识一个类。如果不再是这种情况,那么你就会遇到麻烦。

只要您永远不需要从同一个类加载器访问这两个库,您就可以解决这个问题,然后 JVM 可以很好地处理它(因为 FQCN加上类加载器在 JVM 内部用于在运行时唯一标识一个类)。

故意这样做的唯一情况是,如果某些库以二进制兼容的方式重新实现另一个类的类。有关示例,请参见log4j-over-slf4j

于 2013-11-04T15:04:56.027 回答
1

没有任何内容表明您不能拥有两个具有相同包/类名的类。

当您在类路径中不小心有两个版本的库时,这种情况总是会发生,从而导致诸如IncompatibleClassChangeError或获得错误版本之类的事情,因为您受类加载顺序的支配。

Eclipse,OTOH,除了加载在类路径中遇到的第一个类之外,还必须对这些类做一些事情。你不能重命名为已经存在的东西,因为那没有任何意义。

从已经存在的东西下重命名可能是一个错误,但不能保证是一个错误,因为您可能正在修复一个命名问题,而不仅仅是创建一个新的/不同的问题。

于 2013-11-04T15:08:46.277 回答