何年にもわたって、私はinstanceof
可能な限り避けるように努めてきました。必要に応じて、ポリモーフィズムまたはビジターパターンを使用します。状況によってはメンテナンスが簡単になると思いますが…他に注意すべき欠点はありますか?
しかし、私はそれをJavaライブラリのあちこちで見ているので、その場所があると思いますか?どのような状況でそれが望ましいですか?やむを得ないことはありますか?
何年にもわたって、私はinstanceof
可能な限り避けるように努めてきました。必要に応じて、ポリモーフィズムまたはビジターパターンを使用します。状況によってはメンテナンスが簡単になると思いますが…他に注意すべき欠点はありますか?
しかし、私はそれをJavaライブラリのあちこちで見ているので、その場所があると思いますか?どのような状況でそれが望ましいですか?やむを得ないことはありますか?
のストック実装に間違いなくその場所があり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
は、利用可能な最良のオプションだと思います。
悪い習慣は、たくさんのinstanceof
sを並べて配置し、それらに従ってオブジェクトのさまざまなメソッドを呼び出すことです(もちろんキャスト)。これはおそらく、階層を再考し、おそらくリファクタリングする必要があることを反映しているでしょう。
純粋な OO モデルの内部にいるときは、instanceof
間違いなくコードの匂いがします。
ただし、100% OO モデルを使用していない場合、または外部からオブジェクトを注入する必要がある場合は、instanceof または同等のもの ( isXXX()
、getType()
、 ...) を使用できます。
一般的な「ルール」は、特に型階層を制御し、たとえばサブタイプのポリモーフィズムを使用できる場合は、可能な限り避けることです。アイデアは、オブジェクトにそれがどのタイプであるかを尋ねて何かをするのではなく、オブジェクトに何らかのアクションを実行するよう直接的または間接的に Visitor (本質的に二重ポリモーフィズム) を介して要求することです。
キャスト前の健全性チェックとして使用できます。オブジェクトが正しい型であることを確認するだけでなく、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.
}
悪臭がする可能性があることに同意します。多くの instanceof は、特に連結された if ブロックでは、悪臭を放っています。
時々、あなたが予期しない方法で動作することがあります... 私が一度起こったこと:
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
(私の場合、これはプロキシオブジェクトを作成する休止状態が原因で発生しました....しかし、instanceofに依存するコードが危険な場合にすぎません)
クリエーション工場の場合はどうですか?例えば
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();
}