java 布尔表达式_java - 布尔值,条件运算符和自动装箱
java - 布尔值,条件运算符和自动装箱
为什么抛出false
public static void main(String[] args) throws Exception {
Boolean b = true ? returnsNull() : false; // NPE on this line.
System.out.println(b);
}
public static Boolean returnsNull() {
return null;
}
虽然这不是
public static void main(String[] args) throws Exception {
Boolean b = true ? null : false;
System.out.println(b); // null
}
?
顺便提一下,该解决方案是通过2377135880046604321替换false,以避免null被拆箱至boolean - 这是不可能的。 但这不是问题。 问题是为什么? JLS中是否有任何引用证实了这种行为,尤其是第二种情况?
4个解决方案
89 votes
不同之处在于Boolean方法的显式类型会影响编译时表达式的静态类型:
E1: `true ? returnsNull() : false` - boolean (auto-unboxing 2nd operand to boolean)
E2: `true ? null : false` - Boolean (autoboxing of 3rd operand to Boolean)
请参阅Java语言规范,第15.25节“条件运算符”?:
对于E1,第2和第3个操作数的类型分别为Boolean和Boolean,因此本节适用于:
如果第二个和第三个操作数之一是boolean类型,另一个类型是Boolean类型,那么条件表达式的类型是boolean。
由于表达式的类型是Boolean,因此必须将第二个操作数强制转换为Boolean.编译器将自动取消装箱代码插入第二个操作数(返回值false),使其类型为E1.这当然会导致来自null的NPE 在运行时返回。
对于E2,第2和第3个操作数的类型分别为Boolean(不是像E1中的Boolean)和false,因此不适用特定的输入条款(请阅读'em!),因此最终的“其他”条款适用:
否则,第二和第三操作数分别是S1和S2类型。 设T1是将拳击转换应用于S1所产生的类型,让T2为应用到S2的装箱转换所产生的类型。 条件表达式的类型是将捕获转换(第5.1.10节)应用于lub(T1,T2)(第15.12.2.7节)的结果。
S1 == Boolean(见§4.1)
S2 == Boolean
T1 == box(S1)== Boolean(参见§5.1.7中的拳击转换列表中的最后一项)
T2 ==方框(S2)==`布尔值
lub(T1,T2)== Boolean
因此条件表达式的类型为Boolean,第3个操作数必须强制转换为Boolean.编译器为第3个操作数(false)插入自动装箱代码。 第二个操作数不需要E1中的自动拆箱,因此返回null时不会自动取消装箱NPE。
这个问题需要类似的类型分析:
Java条件运算符?:结果类型
Bert F answered 2019-06-04T05:30:03Z
22 votes
这条线:
Boolean b = true ? returnsNull() : false;
内部转变为:
Boolean b = true ? returnsNull().getBoolean() : false;
执行拆箱; 因此:null.getBoolean()将产生NPE
这是使用自动装箱时的主要缺陷之一。 这种行为确实记录在5.1.8 JLS中
编辑:我认为拆箱是由于第三个运算符是布尔类型,如(隐式强制转换):
Boolean b = (Boolean) true ? true : false;
jjungnickel answered 2019-06-04T05:30:59Z
16 votes
从Java语言规范,第15.25节:
如果是第二个和第三个之一 操作数的类型为boolean和 另一种类型是布尔型, 那么条件的类型 表达式是布尔值。
因此,第一个示例尝试调用Boolean.booleanValue(),以便根据第一个规则将Boolean转换为boolean。
在第二种情况下,第一个操作数是null类型,当第二个操作数不是引用类型时,应用自动装箱转换:
否则,第二和第三 操作数是S1和S2类型 分别。 设T1是那种类型 应用拳击的结果 转换为S1,让T2成为 应用拳击造成的类型 转换为S2。 的类型 条件表达式就是结果 应用捕获转换 (§5.1.10)至lub(T1,T2)(§15.12.2.7)。
axtavt answered 2019-06-04T05:31:59Z
0 votes
我们可以从字节代码中看到这个问题。 在main的字节码的第3行,3: invokevirtual #3 // Method java/lang/Boolean.booleanValue:()Z,值为null的装箱布尔值,invokevirtual方法java.lang.Boolean.booleanValue,它当然会抛出NPE。
public static void main(java.lang.String[]) throws java.lang.Exception;
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: invokestatic #2 // Method returnsNull:()Ljava/lang/Boolean;
3: invokevirtual #3 // Method java/lang/Boolean.booleanValue:()Z
6: invokestatic #4 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
9: astore_1
10: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_1
14: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
17: return
LineNumberTable:
line 3: 0
line 4: 10
line 5: 17
Exceptions:
throws java.lang.Exception
public static java.lang.Boolean returnsNull();
descriptor: ()Ljava/lang/Boolean;
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=1, locals=0, args_size=0
0: aconst_null
1: areturn
LineNumberTable:
line 8: 0
Yanhui Zhou answered 2019-06-04T05:32:31Z
java 布尔表达式_java - 布尔值,条件运算符和自动装箱相关推荐
- java随机布尔值_Java 布尔值(Boolean)
1.Java 布尔值 通常,在编程中,将需要一个只能具有两个值之一的数据类型,表示逻辑判断条件的真假. 为此,Java具有boolean数据类型,该数据类型可以是值true或false. 2.bool ...
- java中怎么定义true或false_为什么Java中的布尔值只接受true或false? 为什么也不要1或0?...
有什么理由为什么Java布尔值仅采用true或false为什么不采用1或0? 这不是一个复杂的问题,但是我也没有理由反对. 您忘记了FILE_NOT_FOUND 因为它是强类型的 在Java中,只能使 ...
- java返回一个布尔值_关于java:返回布尔值的方法
好的,所以我的问题是关于布尔值的回报. 对于我的Comp Sci作业,我必须使用方法制作课程注册程序,其中之一是添加课程方法. 基本上,您在目录中搜索该班级,如果匹配,则将其添加到学生时间表中,并返回 ...
- java 布尔表达式_Java中的布尔表达式优化
考虑Java中的以下方法: public static boolean expensiveComputation() { for (int i = 0; i < Integer.MAX_VALU ...
- 第三次学JAVA再学不好就吃翔(part64)--自动装箱和自动拆箱
学习笔记,仅供参考 自动装箱和自动拆箱 装箱:把基本类型转换为包装类类型 int x = 100; Integer i1 = new Integer(x); 拆箱:把包装类类型转换为基本类型 int ...
- oracle 布尔转换java布尔_java 布尔值一种赋值方法
解决在配置Oracle数据库连接错误问题 项目开发使用的Oracle,但是使用了不同的版本的Oracle数据库.然后自己在电脑上安装了2个连接客户端,版本分别是: 10.2.0 12.1.0 用Toa ...
- c# java 语法_Java与C#的语法区别
1.作用域 在java中 { { int a=1; } int a=2;//以上a作用域外的以下,再声明同名的变量,是允许的: } 在C#中,以上是不允许的[只要在同一个作用域内,以上或以下的代码中 ...
- java 自动装箱自动拆箱
1.Java数据类型 在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference ...
- java 类库_Java基础类库
面向对象的核心-类和对象 类的语法定义 类的修饰符 static可以修饰变量和方法,称为类变量.类方法,它们属于类本身.不被static修饰的变量和方法称为实例变量.实例方法,属于类的实例. 在类准备 ...
最新文章
- 软件开发经验总结(五)读源代码的艺术
- 北京内推 | 地平线视觉算法团队招聘视觉算法实习生
- 在WPF程序中打开网页:使用代理服务器并可进行JS交互
- 自动化测试用例设计原则
- core和node开发小程序_node+微信小程序实现商城案例
- 融云通讯服务器,vue使用融云即时通讯,老是报了发送失败,服务器超时
- python列表嵌套元组拆分,将包含整数和字符串的列表转换为嵌套元组Python
- xml模块、项目开发过程
- 05 | 服务编排层:Pipeline 如何协调各类 Handler ?
- JAX-RPC学习笔记(1)-Hello World!
- 【阿里云IoT YF3300】6.物联网设备报警配置
- 韦福怎么编译c 语言,c语言第1章 绪论.ppt
- Activiti7工作流引擎介绍
- 如何解决“数据错误,循环冗余检查”
- 欧普LED灯维修记录及原理解密
- 【NOIP2018模拟赛2018.8.28】video
- 【WEB】前端系统配色方案(全览)
- boundschecher2
- 基于DCT变换图像去噪算法的进一步优化(100W像素30ms)
- 网络空间技能大赛A模块(乱)
热门文章
- HALCON示例程序measure_chip.hdev芯片封装检测
- java class 关键字_java关键字及其作用
- 驻定相位原理(POSP)的简单应用
- centos 安装 MatConvNet (gpu)
- 如何让Latex公式字体变小
- mysql查询的时候会涉及到锁_Mysql 查询 锁的问题?
- 获取当前日期0点及23点59的时间戳
- spring指导的index.html在spring文件夹中的位置
- MYSQL:基础——触发器
- 求数组中的最小子数组,时间复杂度o(n),java