java - 相等检查后使用 Long 的 NullPointerException

标签 java casting nullpointerexception long-integer

这让我很震惊。

如果您有一个 Java Long 变量,并且您使用 == 运算符检查原始值是否相等,则该值的运行时类型将更改为原始 long。

随后检查变量的空值然后抛出意外的 NullPointerException。

所以在测试类中:

public class LongDebug {

public static void main(String[] args) {
    Long validValue = 1L; 
    Long invalidValue = -1L;
    Long nullValue = null;

    System.out.println("\nTesting the valid value:");
    testExpectedBehaviour(validValue);
    testUnExpectedBehaviour(validValue);

    System.out.println("\nTesting the invalid value:");
    testExpectedBehaviour(invalidValue);
    testUnExpectedBehaviour(invalidValue);

    System.out.println("\nTesting the null value:");
    testExpectedBehaviour(nullValue);
    testUnExpectedBehaviour(nullValue);
}

/**
 * @param validValue
 */
private static void testExpectedBehaviour(Long value) {
    if (value == null || value == -1) System.out.println("Expected: The value was null or invalid");
    else System.out.println("Expected: The value was valid");
}

private static void testUnExpectedBehaviour(Long value) {
    try {
        if (value == -1 || value == null) System.out.println("Unexpected: The value was null or invalid");
        else System.out.println("Unexpected: The value was valid");
    } catch (NullPointerException e) {
        System.out.println("Unexpected: The system threw an unexpected NullPointerException");
    }
}
}

我得到的结果是:

Testing the valid value:
Expected: The value was valid
Unexpected: The value was valid

Testing the invalid value:
Expected: The value was null or invalid
Unexpected: The value was null or invalid

Testing the null value:
Expected: The value was null or invalid
Unexpected: The system threw an unexpected NullPointerException

这是符合规范还是 JDK 中的错误?

最佳答案

问题是:

value == -1 || value == null

表达式从左到右求值,因为 Long 必须先拆箱,JVM 将其转换为:

value.longValue() == -1 || value == null

value.longValue()valuenull 参数时抛出 NullPointerException。它永远不会到达表达式的第二部分。

它在顺序不同时有效:

value == null || value == -1

因为如果 valuenull,第二部分(当 valuenull) 由于 boolean 表达式 short-circuit evaluation 从未被执行.

Is this on spec or a bug in the JDK?

当然这不是错误。原始值包装器的拆箱方式符合规范(5.1.8. Unboxing Conversion):

  • If r is a reference of type Long, then unboxing conversion converts r into r.longValue()

应用拆箱后,剩下的就是标准的Java。

关于java - 相等检查后使用 Long 的 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12686718/

相关文章:

java - 需要一些关于如何解码从 HERE-OLP 以二进制格式下载的 protobuf 文件的建议

java - 如何将字符串数组翻译为另一种语言?

java - java 中的 NullPointerException (javafx)

android - 如何在同一个 Activity 中使用 Camera 和 MediaRecorder?

java - 使用wordnet在java中查找单词的词根

转换/不转换时 C# 无限值错误

php - 如何在 MySQL 或 PHP 中将 32 位整数从无符号转换为有符号?

xml - 如何将 xpath 返回的 xml 数组转换为 Postgres 中的 int 数组

android - SearchView展开抛出空指针异常

java - 如何读取Web项目中的内部文件