在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; ... }
这里看起来非常有害,但是在我的具体情况下,我需要使用水平滚动来浏览我的源代码,而且这种情况使得已经很糟糕的程序变得更糟。
根据您的经验,这种情况下的最佳做法是什么?
我感觉到你的痛苦,无论你使用什么解决方案,有两个同名的类的事实足以让人困惑。
有几个解决方案的解决方法:
- 如果这是你的代码,只需重命名其中一个(或两者)
- 如果这是图书馆(这更有可能)进口更常用的类,完全符合另一个,如杰夫奥尔森建议。
- 如果可能的话,尽量避免让他们在同一个班上。
- 你可以编写你自己的
BarFoo
和BazFoo
,除了扩展它们各自的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找到更多信息