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

どちらのソリューションを使用する場合でも、同じ名前のクラスが2つあるという事実は、十分に混乱を招きます。

いくつかの解決策の回避策があります。

  1. これがあなたのコードである場合は、それらの1つ(または両方)の名前を変更するだけです
  2. これがライブラリ(より可能性が高い)である場合は、より一般的に使用されるクラスをインポートし、Jeff Olsonが提案したように、もう1つのクラスを完全に修飾します。
  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

ベストプラクティスは、コードをリファクタリングすることです。

同じクラスで両方を使用するのが通常であるため、どちらのクラスも同じ名前にするべきではありません。したがって、両方に同じ名前を選択することは賢明な選択ではありません。したがって、少なくともそのうちの1つは名前を変更する必要があります。

または、両方を同じクラスで使用するのは通常ではありません。これらは完全に異なる抽象化レベル(データベースアクセスコードやUIコードなど)に属しているためです。コードは、他の場所ではなく、使用する必要がある各クラスを使用するようにリファクタリングする必要があります。 。

于 2013-02-06T21:13:25.850 に答える
4

これらの状況で私が通常行ったことは、クラスで最も一般的に使用されるFooをインポートしてから、もう1つを完全に修飾することです。

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

ここでOP。

時間とともに、私はJava言語のこの制限を回避するための戦略を実際に開発しました。これにいくつかの欠点があるかどうかはわかりませんが(これまでのところ、何も見つかりませんでした)、ある場合は、この質問にコメントしてください。

アイデアは、完全修飾名の最後の部分をパッケージではなくクラスに置き換え、実際のクラスを静的内部クラスとして定義することです。

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

このように私たちは次のようなものを持っています

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

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

これは実際には非常にクリーンな方法です。もちろん、それはあなたがコントロールするクラスにのみ適用され、ライブラリには適用されません。

既知の欠点

  • 上司はそのアイデアを気に入らず、ハンマーで指を叩くかもしれません。
  • Eclipseはそのアイデアを気に入らないので、それに慣れる必要があります。
于 2015-10-20T12:22:39.757 に答える
1

Javaと互換性のあるKotlinをご覧になることをお勧めします。

Kotlinに名前の衝突がある場合は、キーワードとして使用して、衝突するエンティティの名前をローカルで変更することで、明確にすることができます。

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 に答える