JDK 8与JDK 10:三元/拆箱的区别
最近的Nicolai Parlog ( @nipafx ) 鸣叫引起了我的注意,因为它引用了关于JDK 8和JDK 10之间行为更改的有趣StackOverflow讨论 ,并询问“为什么?” SerCe 在StackOverflow线程上引用的问题最终归结为在JDK 8和JDK 10之间更改了实现,以正确实现 Java语言规范。
下面的代码清单(略有改编)改编自SerCe在StackOverflow线程上提供的原始示例。
在JDK 10和JDK 8中表现不同的改编示例
public static void demoSerCeExample()
{try{final Double doubleValue = false ? 1.0 : new HashMap<String, Double>().get("1");out.println("Double Value: " + doubleValue);}catch (Exception exception){out.println("ERROR in 'demoSerCeExample': " + exception);}
}
使用JDK 8编译并执行上述代码后,它将生成如下输出:
Double Value: null
使用JDK 10编译并执行上述代码后,它将生成如下输出: ERROR in 'demoSerCeExample': java.lang.NullPointerException
在JDK 8中,三元运算符返回null
以便分配给局部变量doubleValue
,但在JDK 10中,为同一三元语句抛出NullPointerException
。
此示例的两个调整导致一些有趣的观察。 首先,如果将三元运算符中表示的文字常量1.0
指定为Double.valueOf(1.0)
,则JDK 8和JDK 10都将局部变量设置为null
而不是抛出NullPointerException
。 其次,如果使用原始类型double
而不是引用类型Double
声明了局部变量,则无论Java版本和是否使用Double.valueOf(double)
都始终抛出NullPointerException
。 当然,第二个观察是有道理的,因为无论三元运算符如何处理对象或引用,都必须在某个点取消引用以将其分配给原始double
类型,并且在示例中始终会导致NullPointerException
。
下表总结了这些观察结果:
完整的三元声明 |
设置局部变量doubleValue
|
|
JDK 8 | JDK 10 | |
|
null
|
NullPointerException
|
|
NullPointerException
|
NullPointerException
|
|
null
|
null
|
|
NullPointerException
|
NullPointerException
|
对于这个一般的三进制示例,在两个Java版本中都避免NullPointerException
的唯一方法是将局部变量声明为引用类型Double
(无需取消装箱)并使用Double.valueOf(double)
以便在整个过程中都使用引用Double
三元而不是原始的double
。 如果仅通过指定1.0
隐含原始double
,则Java Map
返回的Double
在JDK 10中将被隐式取消装箱(取消引用),并导致异常。 根据Brian Goetz的说法 ,JDK 10使实现返回到符合规范的状态。
翻译自: https://www.javacodegeeks.com/2018/06/jdk-ternary-difference.html
JDK 8与JDK 10:三元/拆箱的区别相关推荐
- jdk10与jdk9的区别_JDK 8与JDK 10:三元/拆箱的区别
jdk10与jdk9的区别 最近的Nicolai Parlog ( @nipafx ) 鸣叫引起了我的注意,因为它引用了一个有趣的StackOverflow讨论 ,该讨论涉及JDK 8和JDK 10之 ...
- JDK 1.5 新特性——自动拆箱装箱
1.5版本支持了自动包装和解包操作,对于bool/Boolean,byte/Byte,double/Double,short/Short,int/Integer, long/Long,float/Fl ...
- 可能你不知道的,关于自动装箱和自动拆箱
包装类 我们知道,Java中包含了8种基本数据类型: 整数类型:byte.short.int.long 字符类型:char 浮点类型:float.double 布尔类型:boolean 这8种基本数据 ...
- 包装类-自动装箱和自动拆箱
自动装箱:把基本数据类型转换为包装类型 自动拆箱:把包装类型转换成基本数据类型 public class Demo3 {public static void main(String[] args) { ...
- Java 基本类型与自动装箱、拆箱
基本数据类型 基本类型,或者叫内置类型,是 Jav 中不同于类(class)的特殊类型.它们是我们编程中使用最频繁的类型. Java 是一种强类型语言,第一次申明必须说明数据类型,第一次变量赋值称为变 ...
- Java自动装箱/拆箱
自动装箱和自动拆箱 那么Java中有八大基本数据类型,byte.char.short.int.long.double.float.boolean.而它们有对应的包装类 Byte.Character.S ...
- jdk 5 到 jdk 10各个版本的新特性
jdk5 jdk10各个版本的新特性 JDK1.5新特性: 工程代号为Tiger(老虎) 自从JDK1.3开始,sun维持一个习惯,大约每隔两年发布一个JDK的主版本,以动物命名,期间发布的各个修正版 ...
- 2017.10.16 装箱和拆箱﹑火星车的升级
装箱和拆箱(jdk1.5之后的新特性) 基本类型包装器 区别:基本类型重效率﹑包装器重功能 例: package com.dayuanit.test;public class TestLesson00 ...
- java三元表达式因自动拆箱导致的NPE问题
开发中发生的奇怪的问题,类似如下的代码NPE了... boolean flag = false; Integer a = null; Integer n = flag ? 1 : a; 原来是在计算三 ...
最新文章
- JDOM是JAVA中最常用的一种解析XML的工具
- SpringCloud_Zuul
- 关于jquerymobile的预加载
- mongoose多个连接_连接(connections)
- 设置(TableViewController)通用框架
- Mercurial(Hg)基本操作
- linux arm 64 hard float abi,ARMHF(hard-float ABI for ARM)
- shell 执行失败重试_Smart Retry主要是用来进行方法重试
- keymap in ubuntu
- python的invalid syntax是什么意思_python中出现invalid syntax报错的几种原因
- 老男孩Linux架构师实战课程14期教程
- PCBA方案开发设计—咖啡秤厨房电子秤PCBA方案
- html代码中数学公式,html中使用mathjax数学公式
- 过渡矩阵、线性变换矩阵在对应基下坐标的求法
- 快速学习-web3.js简介与入门
- BIG-ENDIAN VS LITTLE-ENDIAN
- Android性能优化——启动优化简述
- 路由器把服务器的地址修改,路由器修改服务器地址
- AUTOCAD2020入门学习笔记(一)
- JMS RabbitMQ消息代理