在调用instanceof之前需要进行空检查吗?

Joh*_*cke 1287 java null nullpointerexception

null instanceof SomeClass退还false还是扔NullPointerException

And*_*mas 1756

不,在使用instanceof之前不需要进行空检查.

表达x instanceof SomeClassfalse如果xnull.

从Java语言规范,第15.2.2节"类型比较运算符instanceof":

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

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

  • 这个答案比"尝试它"更正确,因为**当前行为**与**保证行为**不同. (367认同)
  • 具体来说,在第8项中,他指出在equals()方法中,一个instanceof运算符有两个目的 - 它验证参数是非空的还是正确的类型."...... [你]不需要单独的空检查." (16认同)
  • 这个问题在Joshua Bloch关于"有效Java"中对象平等的章节中发挥作用 - http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683 (3认同)
  • @GabrielBB,这就像用红笔在红纸上写字一样。即使没有意义,由于通常可以将任意笔与任意纸结合起来,所以这是可能的。在笔中实施“在相同颜色上书写”检查会使技术变得复杂,但几乎没有任何好处。 (3认同)
  • @BenThurley - Java的`instanceof`运算符是大约20年前发布的Java 1.0的一部分.现在以一种破坏现有代码的方式改变行为是不可能的,缺少一些超过巨额成本的好处.二十年前,如果参数可以被强制转换,或者为null参数抛出一个异常,也许可能存在返回true的参数.但是这些定义需要单独的空检查. (2认同)
  • @BenThurley - 过去和现在的Java规范保证了这种行为.我认为卢克的观点解决了实验在确定当前保证行为方面的局限性. (2认同)

Boz*_*zho 257

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

  • (现在需要10秒才能在Google中找到这个问题) (262认同)
  • 太短.一个好的答案提供了背景和解释. (12认同)

Jin*_*won 71

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

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

打印

true
true
false
false
Run Code Online (Sandbox Code Playgroud)

JLS/15.20.2.类型比较运算符instanceof

在运行时,instanceof运算符的结果是true如果RelationalExpression的值不是,null并且可以将引用强制转换为ReferenceType而不引发a ClassCastException.否则结果是false.

API/Class#isInstance(Object)

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

  • @KaiWang 你必须想象在调用 `s instanceof String` 中,`s` 被实际值替换,所以它会变成 `"" instanceof String` 和 `null instanceof String`。像这样思考它可能更有意义。 (2认同)

Rof*_*ion 24

不,这不对.如果它的第一个操作数是,则instanceof返回.falsenull


Att*_*nyi 13

就像一个小窍门:

甚至会回来.(((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).
  }
}
Run Code Online (Sandbox Code Playgroud)

所以Test.test((A)null)将打印a instanceof A: false.)


PS:如果您正在招聘,请不要将此作为面试问题使用.:d

  • 关于你的 PS:如果有人真的在面试中提出问题,那么他们的资历太浅,无法接受面试。在面试中,任何问题的正确或错误答案都不重要。重要的是围绕该主题的**随后的对话**。 (7认同)

dis*_*ame 6

.Java文字null不是任何类的实例.因此它不能是任何类的实例.instanceof 将返回falsetrue因此<referenceVariable> instanceof <SomeClass>返回falsereferenceVariable值为null.

  • 这个解释听起来很奇怪...但我知道你的意思:-) (5认同)

Tri*_*riS 6

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

根据Java 语言规范,使用instanceof.

在运行时,如果 RelationalExpression 的值不为 null,则 instanceof 运算符的结果为 true,并且可以将引用强制转换为 ReferenceType 而不会引发 ClassCastException。否则结果为假

因此我们可以推断 javanull也有一个叫做 type 的东西,并且这个 null 类型在运算符中被检查instanceof,它显然返回 false,因为它需要一个特定的类型。

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

还有一种特殊的 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());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出

null type
I AM A STRING
Run Code Online (Sandbox Code Playgroud)