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