長年にわたり、可能な限りinstanceof
を避けようとしました。該当する場合、ポリモーフィズムまたは訪問者パターンを使用します。状況によっては簡単にメンテナンスが簡単になると思います...他に注意すべき欠点はありますか?
しかし、私はJavaライブラリでそれをあちこちで見るので、私はそれがその場所を持っていると思いますか?
いくつかのケースを想像できます。たとえば、ライブラリのいくつかのオブジェクトを拡張することはできません(拡張するのは不便です)。コレクション。
そのような場合、instanceofを使用してこれらのオブジェクトの処理を区別すると便利だと思います。
新しい小さな機能やバグ修正を追加するためだけに、多くの古いクラスに新しい動作を挿入できないレガシーコードのメンテナンスを確認してください...
equals
のストック実装で間違いなくその場所を持っています。例えば。
public boolean equals ( Object o )
{
if ( this == o )
{
return true;
}
if ( ! (o instanceof MyClass) )
{
return false;
}
// Compare fields
...
}
Instanceofについて知っておくべき1つのすてきなことは、そのLHSがnull
になる可能性があることです。その場合、式はfalse
に評価されます。
オブジェクトのタイプを絶対に知る必要がある場合、instanceof
が最良の選択肢です。
悪い習慣は、たくさんのinstanceof
sを隣同士に並べて、それらに応じてオブジェクトの異なるメソッドを呼び出すことです(もちろんキャスト)。これはおそらく、階層を再考し、おそらくリファクタリングする必要があることを反映しています。
純粋なOOモデルの場合、instanceof
は間違いなくコードの匂いです。
ただし、100%OOモデルを使用していない場合、または外部からモデルにデータを注入する必要がある場合は、instanceofまたは同等の(isXXX()
、getType()
、...)を使用できます。
一般的な「ルール」は、特にyoタイプ階層を制御し、たとえばサブタイプ多態性を使用できる場合に、可能な限り回避することです。目的は、オブジェクトのタイプを尋ねて何かをするのではなく、ビジター(本質的に二重ポリモーフィズム)を介してオブジェクトに直接または間接的に問い合わせて何らかのアクションを実行することです。
悪臭を放つことに同意します。大量のinstanceofは、特にブロックされた場合は連鎖して、悪臭がします。
時々、あなたが予期しないような振る舞いをすることがあります...私が一度起こったこと:
Class B extends A
Class C extends A
B b = new B();
C c = new C();
b instanceof B -> true
b instanceof C -> true
c instanceof C -> true
c instanceof B -> true
(私の場合、これはプロキシオブジェクトを作成する休止状態のために発生しました。
キャスト前の健全性チェックとして使用できます。オブジェクトが正しい型であることを確認することに加えて、それがnullでないことも確認します。
if (o instanceof MyThing) {
((MyThing) o).doSomething(); // This is now guaranteed to work.
} else {
// Do something else, but don't crash onto ClassCast- or NullPointerException.
}
作成工場の場合はどうですか?例えば.
public static Cage createCage(Animal animal) {
if (animal instanceof Dog)
return new DogHouse();
else if (animal instanceof Lion)
return new SteelCage();
else if (animal instanceof Chicken)
return new ChickenWiredCage();
else if (animal instanceof AlienPreditor)
return new ForceFieldCage();
...
else
return new GenericCage();
}