在java导入名称冲突

除非我们改变编译器 ,否则Java会错过import X as Y语法,这在像我这样的情况下很有用:在这个时刻,我正在处理一个具有多个具有相同名称但属于不同包的类的项目。

我想有类似的东西

 import com.very.long.prefix.bar.Foo as BarFoo import org.other.very.long.prefix.baz.Foo as BazFoo class X { BarFoo a; BazFoo b; ... } 

相反,我完成了类似的东西

 class X { com.very.long.prefix.bar.Foo a; org.other.very.long.prefix.baz.Foo b; ... } 

这里看起来非常有害,但是在我的具体情况下,我需要使用水平滚动来浏览我的源代码,而且这种情况使得已经很糟糕的程序变得更糟。

根据您的经验,这种情况下的最佳做法是什么?

我感觉到你的痛苦,无论你使用什么解决方案,有两个同名的类的事实足以让人困惑。

有几个解决方案的解决方法:

  1. 如果这是你的代码,只需重命名其中一个(或两者)
  2. 如果这是图书馆(这更有可能)进口更常用的类,完全符合另一个,如杰夫奥尔森建议。
  3. 如果可能的话,尽量避免让他们在同一个班上。
  4. 你可以编写你自己的BarFooBazFoo ,除了扩展它们各自的Foo类,从而为它们提供自己的名字BazFoo ,什么都不做。 你甚至可以将这些定义为内部类。 例:
 private BarFoo extends com.very.long.prefix.bar.Foo{ //nothing, except possibly constructor wrappers } private BazFoo extends com.very.long.prefix.bar.Foo{ //nothing, except possibly constructor wrappers } class X { BarFoo a; BazFoo b; //... } 

但是有一些缺点:

  • 你必须重新定义构造函数
  • 它不会是完全相同的类,如果你需要将它传递给一个明确检查它的getClass的函数。

你可以通过包装Foo类而不是扩展它们来解决这些缺点,例如:

 private BarFoo { public com.very.long.prefix.bar.Foo realFoo; } private BazFoo extends com.very.long.prefix.bar.Foo{ public com.very.long.prefix.baz.Foo realFoo; } class X { BarFoo a; BazFoo b; //now if you need to pass them someMethodThatTakesBazFoo(b.realFoo); } 

选择最简单的解决方案,祝你好运!

最好的做法是重构代码。

这两个类不应该有相同的名称,因为在同一个类中使用它们是正常的,因此为这两个类选择相同的名称并不是明智的选择。 所以他们至少应该被重新命名。

或者在同一类中使用它们是不正常的,因为它们属于完全不同的抽象层次(例如数据库访问代码和UI代码),代码应该被重构以使用每个必须使用的类而不是其他地方。

我在这些情况下通常做的是在我的班级中导入常用的Foo,然后完全限定另一个:

 import com.very.long.prefix.bar.Foo class X { Foo a; org.other.very.long.prefix.baz.Foo b; ... } 

OP在这里。

随着时间的推移,我开始制定一个解决Java语言限制的策略。 我不知道这是否有一些缺点(到目前为止,我从来没有找到任何),但如果是这样的话,请在这个问题上评论。

这个想法是用一个而不是一个包来替换完全限定名的最后一部分,并且把实际的类定义为静态的内部类。

 class Bar { static class Foo { ... } } 

这样我们就有了类似的东西

 import fqnBar import other.fqnBaz ... Bar.Foo a; Bar.Foo b; 

这实际上是一个非常干净的方式。 当然,它只适用于你控制的类,而不适用于图书馆。

已知的缺点

  • 你的老板可能不喜欢这个想法,用锤子砸你的手指;
  • Eclipse不会喜欢这个想法 ,而且你必须习惯它。

您可能想看看与Java兼容的Kotlin 。

如果Kotlin中存在名称冲突,则可以使用as关键字对本地重命名冲突实体来消除歧义:

 import foo.Bar // Bar is accessible import bar.Bar as bBar // bBar stands for 'bar.Bar' 

你可以在https://kotlinlang.org/docs/reference/packages.html找到更多信息