Rob*_*len 5 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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的结果是:
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
Run Code Online (Sandbox Code Playgroud)
这是符合规范的还是 JDK 中的错误?
这就是问题:
value == -1 || value == null
Run Code Online (Sandbox Code Playgroud)
表达式从左到右计算,并且由于Long必须首先拆箱,JVM 将其转换为:
value.longValue() == -1 || value == null
Run Code Online (Sandbox Code Playgroud)
并在争论时value.longValue()抛出。它永远不会到达表达式的第二部分。NullPointerExceptionvaluenull
当顺序不同时它会起作用:
value == null || value == -1
Run Code Online (Sandbox Code Playgroud)
因为如果valueis ,则由于布尔表达式短路求值,第二null部分(可能导致NullPointerExceptionis )永远不会执行。valuenull
这是符合规范的还是 JDK 中的错误?
当然这不是一个错误。原始值包装器拆箱的方式符合规范(5.1.8.拆箱转换):
- 如果
r是类型的引用Long,则拆箱转换将转换r为r.longValue()
应用拆箱后,剩下的就是标准的Java。
| 归档时间: |
|
| 查看次数: |
13630 次 |
| 最近记录: |