在Java中,不同部署单元中相同包中具有相同名称的类是否会发生冲突

时间:2013-11-04 15:00:16

标签: java eclipse

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

Eclipse项目:

的src / com.abc.d.E

取决于 XYZ.jar ,其中存在 com.abc.d.E.class

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

  

“找到了对重构元素的二进制引用。他们会   没有更新,如果继续,可能会导致问题。“

然后允许这种前向重构。但是,如果想要向后重构为冲突名称,Eclipse中将显示以下消息:

  

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

所以它是

  • 正确的Java
  • 允许Eclipse的行为不一致或
  • .an Eclipse bug?

谢谢。

2 个答案:

答案 0 :(得分:1)

如果两个类都可以访问同一个类加载器(例如,如果两个jar文件都发现它们位于同一个类路径中),则只会加载其中一个(可能是列表中第一个),这将导致各种令人讨厌的结果,特别是如果它们表现不一样的话。

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

一般来说,包名称和类名称​​唯一标识一个类。如果情况不再如此,那么你就会遇到麻烦。

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

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

答案 1 :(得分:1)

没有任何迹象表明你不能拥有两个具有相同包/类名的类。

当您在类路径上意外地拥有两个版本的库时会发生这种情况,导致类似IncompatibleClassChangeError或获取错误的版本,因为您受到类加载顺序的支配。

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

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