7

除非我们更改编译器,否则 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;
    ...
}

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

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

4

5 回答 5

12

我感觉到你的痛苦,无论你使用哪种解决方案,有两个同名的类这一事实已经足够令人困惑了。

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

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

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

于 2013-02-07T19:47:41.910 回答
5

最佳实践是重构代码。

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

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

于 2013-02-06T21:13:25.850 回答
4

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

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

class X {
    Foo a;
    org.other.very.long.prefix.baz.Foo b;
    ...
}
于 2013-02-06T22:27:21.873 回答
1

在这里。

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

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

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

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

import f.q.n.Bar
import other.f.q.n.Baz

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

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

已知的缺点

于 2015-10-20T12:22:39.757 回答
1

您可能想看看与 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找到更多信息

于 2016-04-08T20:46:57.347 回答