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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/271192.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装你自己的perl modules

来源: http://www.cnblogs.com/itech/archive/2012/12/17/2822044.html 安装你自己的perl modules。当没有root权限的时候,需要安装perl modules到自己的home目录下。 来自:http://servers.digitaldaze.com/extensions/perl/modules.html Ins…

项目管理基础:项目的生存周期模型

1、概念介绍软件生命周期模型是一个包含软件产品开发、运行和维护中有关过程、活动和任务的框架,它覆盖了系统从需求定义到系统使用的结束阶段。特点:描述了开发的主要阶段定义了每个阶段需要完成的任务和过程规范了每个阶段的输入输出提供了一个标准框架…

jps显示当前所有java进程pid

很多Java命令都在jdk的JAVA_HOME/bin/目录下面,jps也不例外,他就在bin目录下,所以,他是java自带的一个命令。 jps(Java Virtual Machine Process Status Tool) 是java提供的一个显示当前所有java进程pid的命令,适合在…

jvm内存结构_浅谈JVM内存结构

JVM 可以分为 5 个部分,分别是:类加载器(Class Loader):加载字节码文件到内存。运行时数据区(Runtime Data Area):JVM 核心内存空间结构模型。执行引擎(Execution Engine…

java annotation应用_java Annotation的应用

一、Annotation 示例Override Annotation1 Override2 public void onCreate(Bundle savedInstanceState);二、Annotation 概念及作用1 概念An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and package…

鸿蒙和安卓,到底有什么区别?

对于开发者来说两个最关键的点值得关注:一个是 Beta 版的开发工具,一个是开源网站。开源网站在开发者大会上宣布将 HarmonyOS源代码捐赠给中国开放原子开源基金会,并在大会上公布了鸿蒙系统的开源路线。OpenHarmony 官方源码地址:…

错题集03

(选择一项) 3A: B: C: D: 正确答案是 B解析:LinkedList是实现List,Collection接口,是链表方式进行构建的,根据开发要求不同,可以使用LinkedList实现栈(先进先出)和堆(先进后出)这样的数据结构。(选择一项) 4A: B: C: D: 正确答案是 C解析:由于Hashtable是线程…

从零开始学python人工智能课程_从零开始如何学习人工智能?

想要学习人工智能?这里有一条完整路径资源在本文中,《Analytics India》杂志给出了学习AI的最佳途径。...科技领域的天平正在向人工智能倾斜,IT领域的技术人员正在将AI应用到现有产品中。但是对于企业来说, AI人才才是关键。企业培…

项目管理基础:软件开发的方法介绍

软件开发方法主要有结构化方法、原型化方法、面向对象开发方法、敏捷方法。1、结构化方法结构化方法由结构化分析、结构化设计、结构化程序设计组成,它是一种面向数据流的开发方法。结构化分析:依据分解与抽象的原则,按照系统中数据处理的流程…

类加载器子系统的作用

类加载器子系统的作用

Magento Block设计分析(深入分析)

Magento中Block是一个很重要的组件,它在Block中充当非常重要的角色,下面我们来分析一下Magento中Block是怎样设计的,我们应该怎样使用这个重要的角色。1、Magento Block类图: 图1: 继承Varien_Object的对象都有一个_data类变量,用…

JAVA输出x和y和z_JAVA实例:输入三个整数x,y,z,请把这三个数由小到大输出-吾爱编程网...

今天为大家分享一个java经典实例输入三个整数x,y,z,请把这三个数由小到大输出,相信很多初学者都会学到这道题目,接下来吾爱编程为大家介绍一下程序的相关写法,有需要的小伙伴可以参考一下:1、题目:输入三个整数x,y,z,请…

软件项目管理相关概念介绍笔记

1、成本估算由于软件项目具有可见性差、难定量化的特点,一般情况下很难在项目完成前准确的评估软件项目开发的工作量和费用。通常会根据以往开发类似项目的经验来进行成本估算。也可以将整个项目划分为若干个子系统或按照软件的生命周期的各个阶段分别进行费用估算&…

python爬取微博热搜_Python 超简单爬取微博热搜榜数据

微博的热搜榜对于研究大众的流量有非常大的价值。今天的教程就来说说如何爬取微博的热搜榜。 热搜榜的链接是:用浏览器浏览,发现在不登录的情况下也可以正常查看,那就简单多了。使用开发者工具(F12)查看页面逻辑,并拿到每条热搜的…

LeetCode14 Longest Common Prefix

题意: Write a function to find the longest common prefix string amongst an array of strings. (Easy) 这两天实验室项目太忙了, 老板各种活,只能挑着先水几道easy题,这两个题是昨天做的没来得及写总结。 分析: 暴…

类加载器ClassLoader的角色

类加载器ClassLoader的角色

软件项目管理:进度管理相关概念介绍

软件项目管理当中,项目进度的合理安排是如期完成软件项目的重要基础,也是合理分配资源的重要依据。项目进度安排是项目管理工作当中非常重要的组成部分。软件开发项目进度安排的方式:1、系统最终交付日期已经确定,软件开发部门必须…

ios开发 多人语音聊天_手游语音市场的现状、机遇与挑战

文/手游那点事小鱼原创2014年持续火热的手游市场成就了一大批企业的上市梦,同时也在大环境下产生了对系列手游增值服务的需求。基于玩家对手游社交性的需求,以及借鉴传统端游,页游中成功的社交体系,手游市场逐步出现了对手游语音的…

linux 下运行 tomcat

一开始找不到表名,原来mysql 表名区分大小写。 修改参数 lower_case_table_names1 成功运行后不能通过浏览器访问! 开启8080端口 一、关闭防火墙 firewall-cmd --state 查看状态 [rootVM_7_88_centos /]# firewall-cmd --state running [rootVM_7_88…

软件项目管理:软件工具与开发环境相关知识介绍

1、软件工具相关名词概念软件工具:用来辅助软件开发、运行、维护、管理等过程中的活动软件。软件开发环境:是指支持软件产品开发的软件系统,它由软件工具集和环境集成机制构成。软件工具集:包括支持软件开发相关过程、活动、任务的…