instanceof被认为是不好的做法? 如果是这样,那么在什么情况下仍然是可取的呢?

多年来,我尽可能避免使用instanceof 。 在适用的情况下使用多态或访问者模式。 我想这只是在某些情况下简化了维护工作。还有其他的缺点,应该注意的吗?

但是我确实在Java库中看到它,所以我想它有它的位置? 在什么情况下更可取? 它是不可避免的吗?

我可以想象一些情况,例如你有一些库的对象,你不能扩展(或者这样做会很不方便),也许你的一些对象都是相同的基类混合在一起的采集。
我想在这种情况下,使用instanceof来区分这些对象的一些处理可能是有用的。

同样在一些遗留代码的维护,你不能注入一些新的行为,很多旧的类只是为了添加一个新的小function或一些错误修复…

这绝对是在equals的股票执行中的equals 。 例如

 public boolean equals ( Object o ) { if ( this == o ) { return true; } if ( ! (o instanceof MyClass) ) { return false; } // Compare fields ... } 

关于instanceof的一个很好的事情就是它的LHS可以为null ,在这种情况下,expression式的计算结果为false

我认为,当你绝对需要知道一个对象的types时, instanceof是最好的select。

一个不好的做法是有很多instanceof ,一个接一个,根据他们调用对象的不同方法(当然是铸造)。 这可能会反映出层次结构需要重新思考并可能重构。

当你在一个纯粹的OO模型中时, instanceof肯定是一种代码味道。

但是,如果您没有使用100%的OO模型,或者需要从外部注入东西,那么可以使用instanceof或等价物( isXXX()getType() …)。

一般的“规则”是尽可能地避免它,特别是当控制types层次结构并且可以使用子types多态性时。 这个想法并不是询问对象是什么types,而是对它做些什么,而是直接或间接地通过Visitor(本质上是双重多态)询问对象来执行某些操作。

它可以很好地用于铸造之前的健全检查; 除了检查你的对象是否是正确的types,它也检查它是否为空。

 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与getClass等于方法 (Josh Bloch访谈)
  • 多态性和接口 (请参见关于何时使用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 

(在我这种情况下,这是由于冬眠做代理对象….但只是一个情况下,代码hover在instanceof是有风险的)

在创build工厂的情况下如何? 例如

 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(); }