[转载] JAVA条件表达式的陷阱

参考链接: Java条件表达式中的数字类型提升

Map<String, Integer> map = new HashMap<String, Integer>();   map.put("count", null);   Integer it = map == null ? 0 : map.get("count");  注意:在第三行,会抛出java.lang.NullPointerException信息。因为分析:表达式二的类型为int,整个表达式类型为 Integer,JDK5.0会自动打包,所以表达式三 会获得一个Integer,然后转成int,再转成Integer,如果是NULL在转成int的时候抛出空指针异常。 

  下面的程序将会打印出什么呢? 

  public class DosEquis{     public static void main(String[] args){     char x = 'X';     int i = 0;     System.out.println(true ? x : 0);     System.out.println(false ? i : x);      }   }   这个程序由两个变量声明和两个print语句构成。第一个print语句计算条件表达式(true ? x : 0)并打印出结果,这个结果是char类型变量x的值’X’。而第二个print语句计算表达式(false ? i : x)并打印出结果,这个结果还是依旧是’X’的x,因此这个程序应该打印XX。      然而,如果你运行该程序,你就会发现它打印出来的是X88。这种行为看起来挺怪的。第一个print语句打印的是X,而第二个打印的却是88。它们的不同行为说明了什么呢?      答案就在规范有关条件表达式部分的一个阴暗的角落里。请注意在这两个表达式中,每一个表达式的第二个和第三个操作数的类型都不相同:x是char类型的, 而0和i都是int类型的。混合类型的计算会引起混乱,而这一点比在条件表达式中比在其它任何地方都表现得更明显。你可能考虑过,这个程序中两个条件表达 式的结果类型是相同的,就像它们的操作数类型是相同的一样,尽管操作数的顺序颠倒了一下,但是实际情况并非如此。      确定条件表达式结果类型的规则过于冗长和复杂,很难完全记住它们,但是其核心就是一下三点: 1、如果第二个和第三个操作数具有相同的类型,那么它就是条件表达式的类型。换句话说,你可以通过绕过混合类型的计算来避免×××烦。  2、如果一个操作数的类型是T,T表示byte、short或char,而另一个操作数是一个int类型的常量表达式,它的值是可以用类型T表示的,那么条件表达式的类型就是T。  3、否则,将对操作数类型运用二进制数字提升,而条件表达式的类型就是第二个和第三个操作数被提升之后的类型。      2、3两点是关键。在程序的两个条件表达式中,一个操作数的类型是char,另一个的类型是int。在两个表达式中,int操作数都是0,它可以被表示成 一个char。然而,只有第一个表达式中的int操作数是常量(0),而第二个表达式中的int操作数是变量(i)。因此,第2点被应用到了第一个表达式 上,它返回的类型是char,而第3点被应用到了第二个表达式上,其返回的类型是对int和char运用了二进制数字提升之后的类型,即int。      条件表达式的类型将确定哪一个重载的print方法将被调用。对第一个表达式来说,print(char)将被调用,而对第二个表达式来 说,PrintStream.print(int)将被调用。前一个重载方法将变量x的值作为Unicode字符(X)来打印,而后一个重载方法将其作为 一个十进制整数(88)来打印。      总之,通常最好是在条件表达式中使用类型相同的第二和第三操作数。否则,你和你的程序的读者必须要彻底理解这些表达式行为的复杂规范。      对 语言设计者来说,也许可以设计一个牺牲掉了部分灵活性,但是增加了简洁性的条件操作符。例如,要求第二和第三操作数必须就有相同的类型,这看起来就很合 理。或者,条件操作符可以被定义为对常量没有任何特殊处理。为了让这些选择对程序员来说更加容易接受,可以提供用来表示所有原始类型字面常量的语法。这也 许确实是一个好注意,因为它增加了语言的一致性和完备性,同时又减少了对转型需求。

  

 

转载于:https://blog.51cto.com/3470969/1126884

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

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

相关文章

Linux系统管理初步(七)系统服务管理、chkconfig与systemd 编辑中

Linux系统本身包含了很多服务&#xff0c;CentOS6之前系统的服务用SysV控制&#xff0c;CentOS7改为systemd控制 一、chkconfig服务管理机制 简而言之&#xff0c;chkconfig就是CentOS6以前用来控制系统服务的工具&#xff0c; 常用方法举例 chkconfig --list #列出所有的系统服…

[转载] 菜鸟举例理解字节流和字符流区别

参考链接&#xff1a; Java中的字符流与字节流 Character Stream对比Byte Stream 菜鸟举例理解字节流和字符流区别 按照uft8编码方式存储文档 文档存储路径在D盘下 /** * 按照utf8格式存储文档 */ public static void storeDataByUTF8(){ String path "D:" …

[转载] Java9发布回顾Java 8的十大新特性

参考链接&#xff1a; Java中的DoubleStream mapToObj() java9已经在北京时间9月22日正式发布&#xff0c;开发者可以在oracle jdk官网上下载到最新的jdk9。 今天&#xff0c;我们先来一起复习一下2014年发布的Java 8的十大新特性。先来喝杯java~~~ 按照java升级的传统&…

窗体间传递数据

前言 做项目的时候&#xff0c;winfrom因为没有B/S的缓存机制&#xff0c;窗体间传递数据没有B/S页面传递数据那么方便&#xff0c;今天我们就说下winfrom中窗体传值的几种方式。 共有字段传递 共有字段传递实现起来很方便&#xff0c;就是在窗体类中加个共有字段属性&#xff…

[转载] c语言中检查命令行参数_C中的命令行参数

参考链接&#xff1a; Java中的命令行参数 c语言中检查命令行参数 Command line argument is a parameter supplied to the program when it is invoked. Command line argument is an important concept in C programming. It is mostly used when you need to control your …

MySQL关闭Enterprise Server源码

今天从MySQL官方网站上获知&#xff0c;MySQL宣布关闭Enterprise Server的源码&#xff0c;对于广大开源爱好者来说&#xff0c;这是一个沉重的打击。虽然免费的用户群体一般仅仅使用MySQL Community Server&#xff08;开源免费社区版&#xff09;&#xff0c;但关闭MySQL Ent…

[转载] Java中Scanner用法总结

参考链接&#xff1a; Java之Scanner类 最近在做OJ类问题的时候&#xff0c;经常由于Scanner的使用造成一些细节问题导致程序不通过&#xff08;最惨的就是网易笔试&#xff0c;由于sc死循环了也没发现&#xff0c;导致AC代码也不能通过。。。&#xff09;&#xff0c;因此对S…

os和shutil模块

import os //os模块基本实现了linux系统中所有的命令 os.system(终端命令)&#xff1a;在终端执行命令 os.getcwd():获取当前的工作路径 os.chdir():修改工作路径 os.chmod():修改权限 os.chown():修改属主属组 os.mkdir():创建单个目录&#xff0c;当目录存在时报异常&…

[转载] JAVA语言程序设计(基础篇)第十版课后题答案(第一章)

参考链接&#xff1a; Java中的Scanner和nextChar() JAVA语言程序设计&#xff08;基础篇&#xff09;第十版课后题答案 第一章 第二题 /** Created by ysy on 2018/7/6. */ public class text2 { public static void main(String[] args){ for(int i 0; i < 5; i) Syste…

java.util.Date和java.sql.Date 一点区别

最近无意中发现&#xff0c;在oracle中同一样的一个Date类型字段&#xff0c;存储的日期格式有两种不同的情况&#xff0c;第一种是2011-1-1 12:00:00&#xff0c;第二种是2011-1-1&#xff0c;仔细查找发现在向数据库中写数据的时候定义的变量的问题。 第一种是&#xff1a;ja…

[转载] java中关于用\t格式输出

参考链接&#xff1a; 用Java格式化输出 看了好多人关于\t的用法&#xff0c;感觉找不到自己想要的答案&#xff0c;所以索性就自己输出来看看&#xff0c;如图&#xff1a;这样可以一目了然的看出来&#xff0c;\t&#xff08;制表符&#xff09;的作用就是看前面输出满不满8…

微信抢房软件开发

2019独角兽企业重金招聘Python工程师标准>>> 这两年楼市真可谓是一个"火“字难以形容 经历了长沙两次开盘&#xff0c;都没有抢到&#xff0c;目前还没有买到房子&#xff0c;说说我的悲剧吧&#xff0c;让大伙都开心开心 第一次抢房是今年4月份长沙万科金域国…

[转载] Java——数组习题

参考链接&#xff1a; Java从控制台读取输入的方法 package chap02; import java.util.Scanner; /** * * author admin * date 2020-4-8 * description: * 题目内容&#xff1a; 编写程序&#xff0c; 从控制台读取下面的信息&#xff0c; 每月按22天工作日计算&#xff0c;…

超全Linux备份工具集合,满足你的所有需要!

经常备份计算机上的数据是个好的做法&#xff0c;它可以手动完成&#xff0c;也可以设置成自动执行。许多备份工具拥有不同的功能特性&#xff0c;让用户可以配置备份类型、备份时间、备份对象、将备份活动记入日志及执行更多操作。 1.Rsync这是一款在Linux用户当中颇受欢迎的命…

[转载] Java内存管理-你真的理解Java中的数据类型吗(十)

参考链接&#xff1a; Java中的字符串类String 1 做一个积极的人 编码、改bug、提升自己 我有一个乐园&#xff0c;面向编程&#xff0c;春暖花开&#xff01; 推荐阅读 第一季 0、Java的线程安全、单例模式、JVM内存结构等知识梳理 1、Java内存管理-程序运行过程&#x…

Linux系统安全加固脚本

闲来无事&#xff0c;整理一个系统安全加固脚本&#xff0c;每个公司的要求不一样&#xff0c;所以仅供参考&#xff1a; #!/bin/sh echo "00 */1 * * * /usr/sbin/ntpdate 192.168.1.1 >>/var/log/ntpdate.log" > mycrontab crontab mycrontab rm -rf my…

[转载] 整理下java中stringBuilder和stringBuffer两个类的区别

参考链接&#xff1a; Java中的StringBuffer类 StringBuilder和StringBuffer这两个类在动态拼接字符串时常用&#xff0c;肯定比String的效率和开销小&#xff0c;这是因为String的对象不会回收哦。 其实我一直用StringBuilder这个类&#xff0c;因为可以简写为sb的变量在程序…

11.13 模10计数器设计

.新建一个工程 Family&#xff1a;FLEX10K Available device&#xff1a;EPF10K20TC144-3 2.设置lpm_counter宏单元参数并连接引脚 连接引脚的时候要注意的是&#xff0c;向量线的连接。 3.时序仿真 检查无误后进行下一步 4.载入7448并进行引脚连接 5.分配管脚 再次编译&#x…

[转载] java对象在内存中的结构

参考链接&#xff1a; 了解Java中的类和对象 今天看到一个不错的PPT&#xff1a;Build Memory-efficient Java Applications&#xff0c;开篇便提出了一个问题&#xff0c;在Hotspot JVM中&#xff0c;32位机器下&#xff0c;Integer对象的大小是int的几倍&#xff1f; 我们…

使用valueOf前必须进行校验

每个枚举都是java.lang.Enum的子类,都可以访问Enum类提供的方法,比如hashCode(),name(),valueOf()等..... 其中valueOf()方法会把一个String类型的名称转变为枚举项,也就是枚举项中查找出字面值与该参数相等的枚举项,虽然这个方法很简单,但是JDK却做了一个对于开发人员来说并不…