调用instance of之前需要空值检查吗?

null instanceof SomeClass会返回false还是抛出NullPointerException

314795 次浏览

使用空引用作为instanceof的第一个操作数返回false

instanceof将返回false,如果它的第一个操作数是null

不,在使用instance of之前不需要空值检查。

表达式x instanceof SomeClassfalse,如果xnull

Java11语言规范在第15.20.2节,“类型比较运算符instance of”中简明扼要地表达了这一点。(Java17表达得不够简洁,在引入instance of模式匹配之后。)

"在运行时,结果instanceof运算符是true如果关系表情的值是不是null,引用可能是投到引用类型没有提高ClassCastException。否则结果为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));}}

打印

truetruefalsefalse

JLS/15.20.2.类型比较运算符instance of

在运行时,如果关系表情的值不是null,则instanceof运算符的结果是true,并且引用可以强制转换为引用类型而不会引发ClassCastException。否则结果是false

API/Class#isInstance(Object)

如果此Class对象表示一个接口,则如果指定的Object参数的类或任何超类实现此接口,则此方法返回true;否则返回false。如果此Class对象表示原始类型,则此方法返回false

instanceof运算符不需要显式的null检查,因为如果操作数是null,它不会抛出NullPointerException

在运行时,如果关系表达式的值不是null并且引用可以强制转换为引用类型而不会引发类强制转换异常,则instanceof运算符的结果为true。

如果操作数为null,则instanceof运算符返回false,因此不需要显式空值检查。

考虑下面的例子,

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");         }}

就像花絮

甚至(#1instanceof 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。)


附言:如果你正在招聘,请不要将此用作面试问题。: D

  • 不需要空检查instance of之前
  • 不需要空检查在instance of之后验证为true

以下是null安全的:

if(couldbenull instanceof Comparable comp){return comp.compareTo(somethingElse);}
//java < 14if(couldbenull instanceof Comparable){return ((Comparable)couldbenull).compareTo(somethingElse);}

不,在调用instanceof之前不需要null检查。如果其值为null,它总是返回false。

按照Java语言规范进行比较,使用instanceof

在运行时,如果关系表达式的值不为空,引用可能会在不引发ClassCastException的情况下强制转换为ReReference ceType。否则结果为false

因此,我们可以推断java也有称为null类型的东西,并且在instanceof运算符中检查了这个空类型,这显然返回false,因为它期待特定类型。

Java编程语言中有两种类型:原始类型和引用类型。根据类型和值的Java规格

还有一个特殊的null类型,表达式null的类型,没有名称。因为空类型没有名称,所以不可能声明null类型的变量或强制转换为null类型。空引用是null表达式的唯一可能值类型。空引用始终可以接受扩大引用转换为任何引用类型。

从Java14开始,特别是在LTSJava17中,我们有一个增强的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 17if (testObject instanceof String str) {System.out.println(str.toUpperCase());}}

产出

null typeI AM A STRING