调用instanceof之前需要检查null吗?

发布于 2024-09-03 08:58:02 字数 110 浏览 5 评论 0原文

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

Will null instanceof SomeClass return false or throw a NullPointerException?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

请止步禁区 2024-09-10 08:58:02

不需要,在使用 instanceof 之前不需要进行 null 检查。

如果xnull,则表达式x instanceof SomeClassfalse

Java 11 语言规范在 第 15.20.2 节,“类型比较运算符 instanceof”。 (Java 17 表达得不太简洁,在引入 instanceof 模式匹配之后。)

“在运行时,结果
instanceof 运算符为 true 如果
RelationalExpression 的值是
not null
并且引用可以是
转换为ReferenceType
而不引发 ClassCastException 。
否则结果为false。”

因此,如果操作数为 null,则结果为 false。

No, a null check is not needed before using instanceof.

The expression x instanceof SomeClass is false if x is null.

The Java 11 Language Specification expresses this concisely in section 15.20.2, "Type comparison operator instanceof". (Java 17 expresses this less concisely, after the introduction of instanceof pattern matching.)

"At run time, the result of the
instanceof operator is true if the
value of the RelationalExpression is
not null
and the reference could be
cast to the ReferenceType
without raising a ClassCastException.
Otherwise the result is false."

So if the operand is null, the result is false.

痴情换悲伤 2024-09-10 08:58:02

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

Using a null reference as the first operand to instanceof returns false.

疯狂的代价 2024-09-10 08:58:02

确实是很好的问题。我只是为自己尝试过。

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.类型比较运算符instanceof

在运行时,如果 RelationalExpression 的值不为 nullinstanceof 运算符的结果为 true code> 并且引用可以转换为 ReferenceType,而不会引发 ClassCastException。否则结果为false

API / Class#isInstance(Object)

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

Very good question indeed. I just tried for myself.

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

Prints

true
true
false
false

JLS / 15.20.2. Type Comparison Operator instanceof

At run time, the result of the instanceof operator is true if the value of the RelationalExpression is not null and the reference could be cast to the ReferenceType without raising a ClassCastException. Otherwise the result is false.

API / Class#isInstance(Object)

If this Class object represents an interface, this method returns true if the class or any superclass of the specified Object argument implements this interface; it returns false otherwise. If this Class object represents a primitive type, this method returns false.

娇俏 2024-09-10 08:58:02

不,不是。如果 instanceof 第一个操作数为 null,则返回 false

No, it's not. instanceof would return false if its first operand is null.

伴我老 2024-09-10 08:58:02

正如花絮

即使 (((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 的实例: false。)


PS:如果您正在招聘,请不要将此用作求职面试问题。 :D

Just as a tidbit:

Even (((A)null)instanceof A) will return false.


(If typecasting null seems surprising, sometimes you have to do it, for example in situations like this:

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).
  }
}

So Test.test((A)null) will print a instanceof A: false.)


P.S.: If you are hiring, please don't use this as a job interview question. :D

分分钟 2024-09-10 08:58:02

不需要,在调用 instanceof 之前不需要进行 null 检查。如果其值为 null,则始终返回 false。

根据 Java 语言规范 使用 instanceof 进行比较。

在运行时,如果满足以下条件,instanceof 运算符的结果为 true:
RelationalExpression 的值不为 null,并且引用可以
转换为 ReferenceType 而不引发 ClassCastException。
否则结果为假

因此我们可以推断 java 也有一个名为 null 类型的东西,并且这个 null 类型是在 instanceof 运算符中检查的,它显然返回 false,因为它期望一个具体类型。

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

还有一种特殊的null类型,即表达式null的类型,
它没有名字。因为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

No, a null check is not needed before calling instanceof. It always returns false if its value is null.

As per Java Language Specification for comparison using instanceof.

At run time, the result of the instanceof operator is true if the
value of the RelationalExpression is not null and the reference could
be cast to the ReferenceType without raising a ClassCastException.
Otherwise the result is false

Hence we can infer that java has something called null type also, and this null type is checked in instanceof operator which obviously returns false because it is expecting a specific type.

There are two kinds of types in the Java programming language: primitive types and reference types.
As per Java Specification on types and value

There is also a special null type, the type of the expression null,
which has no name. Because the null type has no name, it is impossible
to declare a variable of the null type or to cast to the null type.
The null reference is the only possible value of an expression of null
type. The null reference can always undergo a widening reference
conversion to any reference type.

From Java 14 onwards and esp. in LTS Java 17 we have an enhanced instanceof. We have pattern matching feature which performs casts after type comparisons.

Example

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

Output

null type
I AM A STRING
稀香 2024-09-10 08:58:02
  • instanceof 之前不需要 null 检查
  • instanceof 验证为 true 之后不需要 null 检查

以下是 null 安全的:

if(couldbenull instanceof Comparable comp){
   return comp.compareTo(somethingElse);
}
//java < 14
if(couldbenull instanceof Comparable){
   return ((Comparable)couldbenull).compareTo(somethingElse);
}
  • null check is not needed before instanceof
  • null check is not needed after instanceof that validates to true

The following are null-safe:

if(couldbenull instanceof Comparable comp){
   return comp.compareTo(somethingElse);
}
//java < 14
if(couldbenull instanceof Comparable){
   return ((Comparable)couldbenull).compareTo(somethingElse);
}
洋洋洒洒 2024-09-10 08:58:02

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

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

如果操作数为 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");
         }  
}

The instanceof operator does not need explicit null checks, as it does not throw a NullPointerException if the operand is null.

At run time, the result of the instanceof operator is true if the value of the relational expression is not null and the reference could be cast to the reference type without raising a class cast exception.

If the operand is null, the instanceof operator returns false and hence, explicit null checks are not required.

Consider the below example,

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

The correct usage of instanceof is as shown below,

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");
         }  
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文