'instanceof' 和 'in' 关键字有什么区别?
What is the difference between the 'instanceof' and 'in' keywords?
为了验证 class 成员资格 ,in
和 instanceof
关键字的行为似乎相同。那么两者有什么区别呢?有什么区别吗? Whosebug 上有几个问题(here or here) where both keywords are given as solutions for this purpose, but there is no mention on the difference between the two or when it is more appropriate to use one over the other. Additionally, the official documention mentions that the in
keyword is equivalent to calling an object's isCase()
method,但没有详细说明 instanceof
关键字的作用。
这两个关键字在 class 继承和接口实现方面的行为似乎相同:
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
主要区别在于 instanceof
是 Java 关键字,而 obj in SomeClass
相当于您在问题中提到的 SomeClass.isCase(obj)
方法调用。
有一个主要含义:instanceof
不能被覆盖,正如 Oracle 文档所说:
The instanceof
operator compares an object to a specified type. You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.
Source: 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
关键字的替代项,则覆盖 Class.isCase()
可能会对您的代码造成一些损坏。
为了验证 class 成员资格 ,in
和 instanceof
关键字的行为似乎相同。那么两者有什么区别呢?有什么区别吗? Whosebug 上有几个问题(here or here) where both keywords are given as solutions for this purpose, but there is no mention on the difference between the two or when it is more appropriate to use one over the other. Additionally, the official documention mentions that the in
keyword is equivalent to calling an object's isCase()
method,但没有详细说明 instanceof
关键字的作用。
这两个关键字在 class 继承和接口实现方面的行为似乎相同:
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
主要区别在于 instanceof
是 Java 关键字,而 obj in SomeClass
相当于您在问题中提到的 SomeClass.isCase(obj)
方法调用。
有一个主要含义:instanceof
不能被覆盖,正如 Oracle 文档所说:
The
instanceof
operator compares an object to a specified type. You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.
Source: 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
关键字的替代项,则覆盖 Class.isCase()
可能会对您的代码造成一些损坏。