java导入中的名称冲突

时间:2013-02-06 21:10:00

标签: java import

除非我们change the compiler,否则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;
    ...
}

这里似乎非常有害,但在我的具体情况下,我需要使用水平滚动才能浏览我的源代码,并且这会让你的程序更糟糕,这已经很糟糕了。

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

5 个答案:

答案 0 :(得分:9)

我觉得你的痛苦,无论你使用哪种解决方案,都有两个同名的类很容易让人困惑。

有几种解决方案解决方法:

  1. 如果这是您的代码,只需重命名其中一个(或两者)
  2. 如果这是库(更有可能)导入更常用的类,完全符合另一个类,正如Jeff Olson建议的那样。
  3. 如果可能的话,尽量避免将它们放在同一个班级。
  4. 您可以编写自己的BarFooBazFoo,除了扩展各自的Foo类之外什么也不做,从而为他们提供自己的名字。您甚至可以将它们定义为内部类。例如:
  5. 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);
    }
    

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

答案 1 :(得分:5)

最佳做法是重构代码。

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

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

答案 2 :(得分:4)

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

import com.very.long.prefix.bar.Foo

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

答案 3 :(得分:1)

OP在这里。

随着时间的推移,我逐渐制定了一种策略来解决Java语言的这种局限性。我不知道这是否有一些缺点(到目前为止我从未发现任何缺点),但如果是这样,请在这个问题上发表评论。

我们的想法是用而不是包替换完全限定名称的最后一部分,并将实际类定义为静态内部类。

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

通过这种方式我们有类似

的东西
import f.q.n.Bar
import other.f.q.n.Baz

...
Bar.Foo a;
Bar.Foo b;

这实际上是一种非常干净的方式。当然它只适用于您控制的类,而不适用于库。

已知缺点

答案 4 :(得分:1)

您可能需要查看与Java兼容的Kotlin

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

element[0].querySelectorAll('input, select')

您可以在https://kotlinlang.org/docs/reference/packages.html

找到更多信息