Java &引用;“的实例”&引用;“的类型”;这个用例是什么?

Java &引用;“的实例”&引用;“的类型”;这个用例是什么?,java,Java,在做一些随意的阅读时,我偶然发现了斯科特·迈尔斯(Scott Meyers)的一句有趣的话 任何时候你发现自己在写作 “如果对象是 键入T1,然后做一些事情,但如果 是T2型的,然后做点什么 否则,“打你自己 我只是想知道为什么Java有“instance of”操作符,而您可以通过重写的方法来做同样的事情?实际使用时间是什么时候?例如: public void eat(Eatable eatable){ if(eatable instanceof fruit){ //direct

在做一些随意的阅读时,我偶然发现了斯科特·迈尔斯(Scott Meyers)的一句有趣的话

任何时候你发现自己在写作 “如果对象是 键入T1,然后做一些事情,但如果 是T2型的,然后做点什么 否则,“打你自己

我只是想知道为什么Java有“instance of”操作符,而您可以通过重写的方法来做同样的事情?实际使用时间是什么时候?

例如:

public void eat(Eatable eatable){
  if(eatable instanceof fruit){
    //direct eat
  }
}



有时,您必须使用其行为(例如源代码)不受您控制的对象,因此您不能始终依赖面向对象的解决方案来解决与类型相关的问题。(尤其是考虑到库的作者不能预料到您可能使用的每一个用例;当然,您可以认为扩展和实现提供了解决方案,但它们比直接类型检查需要更多的努力。)
“instanceof”操作符提供了一种检查对象类型并有条件地执行操作的方法。

避免它是理想的,但有时是必要的

instanceof的使用可能会干扰开/关原则(固体中的“O”)。如果您实现了instanceof测试,那么在创建新的实现类时,可能需要修改您的类


然而,这有时是必要的。例如,它可以用于
Object.equals()
方法的实现中。参数是一个对象——因此该方法可能被任意子类覆盖——但通常需要将其转换为类的类型以进行比较。

在编写类似包装器设计模式的复杂类结构时,您永远不知道将遇到什么类型的对象。在这种情况下,您可以使用operator的实例检查对象。

我实际上在使用第三方库时使用它,并且类是最终类(jerk!)


代码中的if类型do something表示do something应该是类或接口中定义的具有重写行为的方法。但是,这假设您可以控制实现。有时候你不会。当我为一个类
Foo
实现
equals()
时,它通常是这样的:

public boolean equals(Object o) {
  if (o instanceof Foo) {
    Foo that = (Foo) o;
    [ compare this to that ]
  } else {
  return false;
}

因为我覆盖了
等于
签名是强制的,但是我需要知道我是否有一个Foo的实例来进行有意义的比较。

也许这就是为什么他说自己打耳光。)好吧,这是一个如何使用
instanceof
的例子,但没有说明为什么它会出现在语言中。但这只是因为equals是一个古老的方法,今天可能不会以这种方式实现。定义一个类似Comparable的通用Equalable接口会更好,并且可以避免这个问题(当然你不能将任意对象放入集合中,但这也不是一种好的风格)@Voo:good point,但不管是否古老,“equals”是Java平台的一个关键方法,在非平凡的程序中,没有办法避免它。@Voo好的观点。我不能说我喜欢这样写
equals
,这正是我最常使用
instanceof
@Voo的情况——类型擦除使得equals()方法在某些情况下仍然有用,不管引入了泛型。
class Fruit extends Eatable {
}
public boolean equals(Object o) {
  if (o instanceof Foo) {
    Foo that = (Foo) o;
    [ compare this to that ]
  } else {
  return false;
}