出于验证类成员身份的目的,in
和instanceof
关键字的行为似乎相同。那么两者之间有什么区别?根本没有区别吗?关于StackOverflow(here或here)有几个问题,其中两个关键字都是为此目的提供的解决方案,但是没有提及两者之间的区别或者何时更适合使用一个在其他。此外,官方文献中提到了the in
keyword is equivalent to calling an object's isCase()
method,但没有详细说明instanceof
关键字的作用。
两个关键字在类继承和接口实现方面似乎表现相同:
class MyMap extends LinkedHashMap { }
def foo = new LinkedHashMap()
def bar = new MyMap()
println("LinkedHashMap instance is 'in' LinkedHashMap: ${foo in LinkedHashMap}")
println("LinkedHashMap instance is 'instanceof' LinkedHashMap: ${foo instanceof LinkedHashMap}")
println("LinkedHashMap instance is 'in' Map: ${foo in Map}")
println("LinkedHashMap instance is 'instanceof' Map: ${foo instanceof Map}")
println("MyMap instance is 'in' LinkedHashMap: ${bar in LinkedHashMap}")
println("MyMap instance is 'instanceof' LinkedHashMap: ${bar instanceof LinkedHashMap}")
println("MyMap instance is 'in' Map: ${bar in Map}")
println("MyMap instance is 'instanceof' Map: ${bar instanceof Map}")
输出:
LinkedHashMap instance is 'in' LinkedHashMap: true
LinkedHashMap instance is 'instanceof' LinkedHashMap: true
LinkedHashMap instance is 'in' Map: true
LinkedHashMap instance is 'instanceof' Map: true
MyMap instance is 'in' LinkedHashMap: true
MyMap instance is 'instanceof' LinkedHashMap: true
MyMap instance is 'in' Map: true
MyMap instance is 'instanceof' Map: true
答案 0 :(得分:2)
主要区别在于instanceof
是Java关键字,而obj in SomeClass
相当于问题中提到的SomeClass.isCase(obj)
方法调用。
有一个主要含义:instanceof
不能被覆盖,正如Oracle文档所说:
instanceof
运算符将对象与指定类型进行比较。您可以使用它来测试对象是实现特定接口的类的实例,子类的实例还是类的实例。
来源:https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
Class.isCase(obj)
的实现方式如下:
/**
* Special 'Case' implementation for Class, which allows testing
* for a certain class in a switch statement.
* For example:
* <pre>switch( obj ) {
* case List :
* // obj is a list
* break;
* case Set :
* // etc
* }</pre>
*
* @param caseValue the case value
* @param switchValue the switch value
* @return true if the switchValue is deemed to be assignable from the given class
* @since 1.0
*/
public static boolean isCase(Class caseValue, Object switchValue) {
if (switchValue instanceof Class) {
Class val = (Class) switchValue;
return caseValue.isAssignableFrom(val);
}
return caseValue.isInstance(switchValue);
}
来源:org/codehaus/groovy/runtime/DefaultGroovyMethods.java#L1121
如您所见,根据源代码,Groovy的obj in SomeClass
不是instanceof
的别名,因为它的作用还更多。但是,有一件值得一提的重要事情-您可以覆盖isCase()
的实现,但是不能更改instanceof
Java关键字的行为。如果您将Class.isCase()
替代Java的instanceof
关键字,则覆盖canvas
可能会对您的代码造成一些损害。