代码:
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的时候抛出空指针异常。
附一篇博客:ava 条件表达式(即三元操作符)的陷阱
地址:http://apps.hi.baidu.com/share/detail/5319426
下面的程序将会打印出什么呢?
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类型的。混合类型的计算会引起混乱,而这一点比在条件表达式中比在其它任何地方都表现得更明显。你可能考虑过,这个程序中两个条件表达式的结果类型是相同的,就像它们的操作数类型是相同的一样,尽管操作数的顺序颠倒了一下,但是实际情况并非如此。
确定条件表达式结果类型的规则过于冗长和复杂,很难完全记住它们,但是其核心就是一下三点:
如果第二个和第三个操作数具有相同的类型,那么它就是条件表达式的类型。换句话说,你可以通过绕过混合类型的计算来避免大麻烦。
如果一个操作数的类型是T,T表示byte、short或char,而另一个操作数是一个int类型的常量表达式,它的值是可以用类型T表示的,那么条件表达式的类型就是T。
否则,将对操作数类型运用二进制数字提升,而条件表达式的类型就是第二个和第三个操作数被提升之后的类型。
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)来打印。
总之,通常最好是在条件表达式中使用类型相同的第二和第三操作数。否则,你和你的程序的读者必须要彻底理解这些表达式行为的复杂规范。
对 语言设计者来说,也许可以设计一个牺牲掉了部分灵活性,但是增加了简洁性的条件操作符。例如,要求第二和第三操作数必须就有相同的类型,这看起来就很合 理。或者,条件操作符可以被定义为对常量没有任何特殊处理。为了让这些选择对程序员来说更加容易接受,可以提供用来表示所有原始类型字面常量的语法。这也 许确实是一个好注意,因为它增加了语言的一致性和完备性,同时又减少了对转型需求。
分享到:
相关推荐
Java表达式是程序中进行计算的部分,它们可以是简单的变量引用,也可以是复杂的运算组合。在Java中,理解操作符优先级和类型转换是解决表达式谜题的关键。例如,`==`用于比较两个对象是否相等,而非赋值;`+=`是复合...
Java作为一门广泛使用的编程语言,其基础知识的掌握对于程序员来说至关重要。然而,即便是经验丰富的开发者也可能在...本资源的"01第一讲:Java基础方面陷阱"应包含了对这些知识点的详细讲解,值得Java程序员学习参考。
### Java常见疑惑与陷阱 #### 一、Java基础的常见陷阱 **1.1 不一样的数字的宽类型和窄类型** 在Java中,当我们处理不同的数值类型时,可能会遇到一些意料之外的行为。例如,当一个`byte`类型的数据与一个`int`...
Java中的问号表达式,通常被称为三元运算符或条件运算符,是Java编程语言中一个简洁的语法结构,用于根据条件返回一个值。在Java中,问号表达式具有以下形式:`条件 ? 结果1 : 结果2`。这个表达式会先评估条件,如果...
### Java面试中的陷阱知识点解析 在Java面试过程中,面试官往往会通过一些问题来考察应聘者对Java基础知识的理解深度以及在实际编程中解决问题的能力。本文将根据提供的标题、描述及部分内容,整理并归纳出一系列...
13. **Lambda表达式与函数式编程**:Java 8引入了Lambda表达式,它简化了匿名内部类的使用,使得函数式编程成为可能。理解Lambda的语法、函数式接口和Stream API的使用是现代Java开发的基本要求。 14. **Junit与...
- 断言用于调试阶段验证假设条件,如果断言表达式为`false`,将抛出`AssertionError`异常。 - 断言的使用需在编译时通过`-ea`参数开启,运行时也可以通过系统属性控制断言的启用与禁用。 #### 6. 垃圾回收(GC)的...
12. **Lambda表达式与函数式编程**:理解Java 8引入的Lambda表达式的语法和用途,以及Stream API的使用。 13. **注解(Annotation)**:理解注解的基本用法,知道自定义注解和元注解,以及注解处理器的应用。 14. ...
4. **高级特性详解**:深入探讨了更复杂的正则表达式特性,如回溯控制、条件匹配、命名捕获组等,并通过具体例子展示如何利用这些特性编写更高效、更灵活的正则表达式。 5. **解决常见问题**:针对性能不佳、误报、...
10. **常见问题与陷阱**:正则表达式中的常见错误和陷阱,如无限循环、贪婪与懒惰量词的区别,以及如何避免这些问题。 "正则表达式傻瓜式宝典"作为一本面向初学者的指南,应该以浅显易懂的方式,通过丰富的示例和...
7. **正则表达式引擎**:讨论不同的正则表达式引擎(如Perl兼容、ECMAScript等)的差异,以及它们在不同编程语言(如JavaScript、Python、Java等)中的实现。 8. **实例解析**:提供大量实际例子,帮助学习者通过...
9. **在不同环境中的应用**:了解JavaScript、Python、Java、Perl等语言中正则表达式的异同,有助于更好地适应不同的编程需求。 通过学习上述知识点,结合《正则表达式入门经典》和“正则表达式解释器实现原理”,...
5. **正则表达式引擎的差异**:书中讨论了不同的正则表达式引擎(如Perl、JavaScript、Java、.NET等)之间的差异,这对于跨平台开发或使用不同语言的开发者来说非常重要。 6. **实战应用**:书中包含大量实例,涵盖...
【JAVA面试陷阱详解】 在Java面试中,面试官常常会设置一些陷阱问题,考察候选人的基础知识和理解深度。以下是一些常见的陷阱问题及其解析: 1. **final, finally, finalize的区别** - `final`:这是一个修饰符,...
Java中的正则表达式是用于字符串处理的强大工具,它允许开发者定义搜索模式,这些模式可用于...通过示例代码和细致的解释,本文深入讲解了Java正则表达式的使用方法和常见陷阱,帮助开发者在实际应用中更加得心应手。
Java面试中的陷阱往往涉及到对语言核心概念的深度理解,这些陷阱涵盖了从基本语法特性到高级设计模式的应用。面试官通常会通过一些看似简单但实际上需要深入理解的问题来测试候选人的技能和经验。 首先,我们来看看...