`

java 条件表达式(即三元操作符)的陷阱[转]

阅读更多

转: 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。它们的不同行为说明了什么呢?

 

 

答案就在规范有关条件表达式部分的一个阴暗的角落里。请注意在这两个表达式中,每一个表达式的第二个和第三个操作数的类型都不相同:xchar类型的,而0i都是int类型的。混合类型的计算会引起混乱,而这一点比在条件表达式中比在其它任何地方都表现得更明显。你可能考虑过,这个程序中两个条件表达式的结果类型是相同的,就像它们的操作数类型是相同的一样,尽管操作数的顺序颠倒了一下,但是实际情况并非如此。

确定条件表达式结果类型的规则过于冗长和复杂,很难完全记住它们,但是其核心就是一下三点:

  • 如果第二个和第三个操作数具有相同的类型,那么它就是条件表达式的类型。换句话说,你可以通过绕过混合类型的计算来避免大麻烦。
  • 如果一个操作数的类型是TT表示byteshortchar,而另一个操作数是一个int类型的常量表达式,它的值是可以用类型T表示的,那么条件表达式的类型就是T
  • 否则,将对操作数类型运用二进制数字提升,而条件表达式的类型就是第二个和第三个操作数被提升之后的类型

23两点是关键。在程序的两个条件表达式中,一个操作数的类型是char,另一个的类型是int。在两个表达式中,int操作数都是0,它可以被表示成一个char。然而,只有第一个表达式中的int操作数是常量(0),而第二个表达式中的int操作数是变量(i)。因此2点被应用到了第一个表达式上,它返回的类型是char,而第3点被应用到了第二个表达式上,其返回的类型是对intchar运用了二进制数字提升之后的类型,即int

 

 

条件表达式的类型将确定哪一个重载的print方法将被调用。对第一个表达式来说,print(char)将被调用,而对第二个表达式来说,PrintStream.print(int)将被调用。前一个重载方法将变量x的值作为Unicode字符(X)来打印,而后一个重载方法将其作为一个十进制整数(88)来打印。

 

 

总之,通常最好是在条件表达式中使用类型相同的第二和第三操作数。否则,你和你的程序的读者必须要彻底理解这些表达式行为的复杂规范。

 

 

对 语言设计者来说,也许可以设计一个牺牲掉了部分灵活性,但是增加了简洁性的条件操作符。例如,要求第二和第三操作数必须就有相同的类型,这看起来就很合 理。或者,条件操作符可以被定义为对常量没有任何特殊处理。为了让这些选择对程序员来说更加容易接受,可以提供用来表示所有原始类型字面常量的语法。这也 许确实是一个好注意,因为它增加了语言的一致性和完备性,同时又减少了对转型需求。

 

                                           

摘自《Java™ Puzzlers -- Puzzle 8: Dos Equis》

作者:Joshua Bloch, Neal Gafter

我的理解:

对于A?B:C

如果b和c是同一类型T,则T是条件表达式的返回类型。

如果b是类型T,c是int的常量,则T是条件表达式的返回类型。

如果b是类型T,c是int的变量,则返回类型被提升为int。

这个类型不知道能不能不是基础类型的呢?

实验证明,是可以的。

分享到:
评论
1 楼 today2008 2013-08-20  
如果b是类型T,c是int的常量,则T是条件表达式的返回类型。 这样说其实是不对的

如果T的范围比 int 大,那肯定返回类型是T
如过T的范围比 int 小:一种情况是, int常量可以转换为T 类型,那返回T类型, 如果不能转换为T 类型,那 返回int类型

相关推荐

    编译原理算术表达式转三元式

    合工大系统软件综合设计编译原理分册 《算术表达式转三元式》用java写的,含有图形界面和所使用的文法 构造算符优先分析器,根据文法分析输入语句,求first_vt、last_vt集,构造分析表,输出规约过程,一边扫描输出...

    将算术表达式转换成间接三元式的程序实现报告

    "将算术表达式转换成间接三元式的程序实现报告" 本报告旨在介绍一个将算术表达式转换成间接三元式的程序实现报告。该程序将用户输入的算术表达式转换成间接三元式,以便于后续的编译和优化处理。 首先,本报告将...

    Java正则表达式 Java 正则表达式

    Java正则表达式是Java语言中用于处理字符串的强大工具,它允许程序员进行复杂的字符串匹配、查找和替换操作。正则表达式(Regular Expression)是一种模式匹配语言,通过特定的语法来描述字符串的模式,用于在文本中...

    常用java正则表达式

    ### 常用Java正则表达式知识点 #### 一、引言 正则表达式是一种强大的工具,用于处理文本并查找模式。多种编程语言,包括Perl、PHP、Python、JavaScript以及Java等均内置了对正则表达式的支持。本文将详细介绍Java...

    确保正确使用三元条件表达式的ESLint规则

    在JavaScript开发中,正确使用三元条件表达式(也称为三目运算符)是提高代码可读性和效率的重要方面。`eslint-plugin-proper-ternary` 是一个专门针对这一问题的ESLint插件,旨在帮助开发者遵循最佳实践,避免潜在...

    java 三元操作符的使用

    在Java中,三元操作符是一种简洁的条件表达式,用于在两个值之间进行选择。

    使用Java正则表达式分析处理日志

    本篇将围绕“使用Java正则表达式分析处理日志”这一主题,探讨如何利用Java的正则表达式功能来提取、过滤和操作日志数据。 首先,我们需要理解正则表达式的基本概念。正则表达式(Regular Expression)是一种模式...

    JAVA正则表达式大全

    在Java编程语言中,正则表达式被广泛应用于数据验证、文本提取和字符串操作。以下是对这些文档标题所涉及的Java正则表达式知识点的详细解释: 1. **正则表达式之道** 这个主题可能涵盖了正则表达式的基础概念,...

    java c++表达式求值(带括号和小数点)

    逆波兰表示法(Reverse Polish Notation,RPN)是一种数学表达式表示方法,它通过消除括号和操作符优先级来简化表达式求值的过程。在这个场景中,我们需要使用Java和C++编程语言来实现一个能够处理带有括号和小数点...

    Java正则表达式.ppt

    在Java中,正则表达式提供了简洁而灵活的方式来处理字符串,使得编程人员能够以更高效的方式实现各种文本操作。 正则表达式的起源可以追溯到20世纪中叶,由Warren McCulloch和Walter Pitts的神经网络理论,以及...

    Java 正则表达式 图片版

    Java正则表达式 Java 正则表达式 图片版 携带方便,查阅方便!~

    Java算术表达式计算类库 ExpressionJ

    **Java算术表达式计算类库 ExpressionJ** ExpressionJ是一个强大的Java库,专门设计用于解析和计算数学算术表达式。这个库对于那些在应用程序中需要动态计算复杂数学表达式的开发者来说,是一个非常有用的工具。它...

    java cron表达式生成器

    Java根据时间戳生成cron表达式,可传入时间范围灵活实现Cron基于日历形式的任务调度时间点,简单简洁,互用性强,可以灵活改动。

    java正则表达式验证

    java使用正则表达式进行校验验证,主要使用了Pattern和Matcher类,直接main方法运行就可以,亲测有效

    Java中缀表达式求值

    Java中缀表达式求值 Java中缀表达式求值是一种常见的计算机算法,用于评估中缀表达式的值。中缀表达式是一种常见的数学表达式形式,但是在计算机中难以直接计算,因为它的运算符优先级和结合性规则使得计算变得复杂...

    Java 正则表达式库

    在Java中,正则表达式(Regular Expression)是一种模式匹配语言,用于处理字符串操作,如查找、替换或提取特定模式的数据。这个库不仅包含了标准Java API中的`java.util.regex`包,还可能包含了一些第三方库,如`...

    Java正则表达式入门介绍.ppt

    Java正则表达式是编程语言Java中用于处理文本的强大工具,它源于早期的神经网络理论和数学家Stephen Kleene的工作,后来在Unix系统中得到广泛应用。在Java中,正则表达式提供了简洁的方法来匹配、查找、替换和提取...

    强大的JAVA正则表达式处理包jakarta-oro

    总的来说,Jakarta ORO是Java开发中一个强大的工具,尤其适合需要频繁和高效正则表达式操作的项目。通过理解和熟练使用这个库,开发者可以提高代码的性能和灵活性,同时也可以解决一些标准库无法处理的复杂文本处理...

    Java正则表达式介绍和练习

    Java正则表达式介绍和练习Java正则表达式介绍和练习Java正则表达式介绍和练习

    java正则表达式使用例子

    Java正则表达式是Java编程语言中用于处理字符串的强大工具,它允许我们通过模式匹配来查找、替换或分割文本。在Android开发中,正则表达式尤其重要,因为它们可以帮助我们验证用户输入、处理文本数据或者进行复杂的...

Global site tag (gtag.js) - Google Analytics