null instanceof SomeClass
会返回 false
还是抛出 NullPointerException
?
不,在使用 instanceof 之前不需要进行空值检查。
如果 x
是 null
,则表达式 x instanceof SomeClass
是 false
。
Java 11 语言规范在 section 15.20.2, "Type comparison operator instanceof" 中简洁地表达了这一点。 (Java 17 expresses this less concisely,在引入 instanceof 模式匹配之后。)
“在运行时,如果 RelationalExpression 的值不为 null,并且可以将引用转换为 ReferenceType 而不会引发 ClassCastException,则 instanceof 运算符的结果为真。否则结果为假。”
因此,如果操作数为空,则结果为假。
使用空引用作为 instanceof
的第一个操作数会返回 false
。
确实很好的问题。我只是为自己尝试。
public class IsInstanceOfTest {
public static void main(final String[] args) {
String s;
s = "";
System.out.println((s instanceof String));
System.out.println(String.class.isInstance(s));
s = null;
System.out.println((s instanceof String));
System.out.println(String.class.isInstance(s));
}
}
印刷
true
true
false
false
JLS / 15.20.2. Type Comparison Operator instanceof
在运行时,如果 RelationalExpression 的值不为 null,并且可以将引用强制转换为 ReferenceType 而不会引发 ClassCastException,则 instanceof 运算符的结果为真。否则结果为假。
API / Class#isInstance(Object)
如果此 Class 对象表示一个接口,则如果指定 Object 参数的类或任何超类实现此接口,则此方法返回 true;否则返回 false。如果此 Class 对象表示原始类型,则此方法返回 false。
s
只是一个对象引用变量。它可能引用一个实际存在的对象(""
),也可能引用一个(该)null
字面量引用。
null
不是字符串数据,无论是什么变量指向它。例如,s instanceof String
与 field.getType().equals(String.class)
不同。
s instanceof String
中 s
被实际值替换,因此将变为 "" instanceof String
和 null instanceof String
。这样想可能更有意义。
不,这不对。如果第一个操作数是 null
,instanceof
将返回 false
。
就像一个花絮:
甚至 (
((A)null)
instanceof A)
也会返回 false
。
(如果类型转换 null
看起来令人惊讶,有时您必须这样做,例如在这样的情况下:
public class Test
{
public static void test(A a)
{
System.out.println("a instanceof A: " + (a instanceof A));
}
public static void test(B b) {
// Overloaded version. Would cause reference ambiguity (compile error)
// if Test.test(null) was called without casting.
// So you need to call Test.test((A)null) or Test.test((B)null).
}
}
所以 Test.test((A)null)
将打印 a instanceof A: false
。)
PS:如果您正在招聘,请不要将此作为求职面试问题。 :D
instanceof
运算符不需要显式 null
检查,因为如果操作数是 null
,它不会抛出 NullPointerException
。
在运行时,如果关系表达式的值不是 null
,则 instanceof
运算符的结果为真,并且可以将引用强制转换为引用类型而不会引发类强制转换异常。
如果操作数是 null
,则 instanceof
运算符返回 false
,因此不需要显式检查 null。
考虑下面的例子,
public static void main(String[] args) {
if(lista != null && lista instanceof ArrayList) { //Violation
System.out.println("In if block");
}
else {
System.out.println("In else block");
}
}
instanceof
的正确用法如下图,
public static void main(String[] args) {
if(lista instanceof ArrayList){ //Correct way
System.out.println("In if block");
}
else {
System.out.println("In else block");
}
}
在 instanceof 之前不需要空检查
在验证为 true 的 instanceof 之后不需要进行空检查
以下是空安全的:
if(couldbenull instanceof Comparable comp){
return comp.compareTo(somethingElse);
}
//java < 14
if(couldbenull instanceof Comparable){
return ((Comparable)couldbenull).compareTo(somethingElse);
}
不,在调用 instanceof
之前不需要检查 null
。如果它的值为 null
,它总是返回 false。
根据 Java Language Specification 使用 instanceof
进行比较。
在运行时,如果 RelationalExpression 的值不为 null,并且可以将引用强制转换为 ReferenceType 而不会引发 ClassCastException,则 instanceof 运算符的结果为真。否则结果为假
因此我们可以推断出 java 也有一个叫做 null
的类型,并且这个 null 类型在 instanceof
运算符中被检查,它显然返回 false,因为它需要一个特定的类型。
Java 编程语言中有两种类型:原始类型和引用类型。根据类型和值的 Java Specification
还有一种特殊的 null 类型,即表达式 null 的类型,它没有名称。因为 null 类型没有名字,所以不可能声明一个 null 类型的变量或强制转换为 null 类型。空引用是空类型表达式的唯一可能值。空引用始终可以进行扩展引用转换为任何引用类型。
从 Java 14 开始,尤其是。在 LTS Java 17 中,我们有一个增强的 instanceof
。我们有模式匹配功能,它在类型比较之后执行强制转换。
例子
public static void main(String[] args) {
Object testObject = "I am a string";
List<Object> testList = null;
if (testList instanceof List) {
System.out.println("instance of list");
} else {
System.out.println("null type");
}
//Enhanced instanceof with type conversion - tested with JDK 17
if (testObject instanceof String str) {
System.out.println(str.toUpperCase());
}
}
输出
null type
I AM A STRING
try it
更正确,因为当前行为与保证行为不同。Effective Java
- amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683 中关于对象相等的章节中发挥了作用