前面讲到赋值运算符的时候,提到“x = x+7”可以被“x += 7”所取代,当然Java编程中给某个变量自加7并不常见,常见的是给某变量自加1,就像走台阶,一般都是一级一级台阶地走,犯不着一下子跳上七级台阶。那么对于变量自加1的情况,既可以写成“x = x+1”,也可以写成“x += 1”,但是早期的Java设计师嫌前面的语句不够简洁,故而创造了新的运算符“++”,该运算符表示给变量自加1,于是“x += 1”可再简化为“x++”。同理,运算符“--”表示给变量自减1,语句“x--”等价于“x -= 1”和“x = x-1”。为深入理解“++”与“--”这两个运算符的作用,不妨运行下面的演示代码观察结果:

		int x = 3;
System.out.println("初始 x="+x);
x++; // 等同于x=x+1或者x+=1
System.out.println("自增1 x="+x);
x--; // 等同于x=x-1或者x-=1
System.out.println("自减1 x="+x);

既然有了自增1运算“++”和自减1运算“--”,那末有没有自乘运算“**”和自除运算“//”呢?很遗憾Java不存在所谓的自乘与自除,倘若自乘运算指的是求某整型变量的平方,还是老老实实地写以下代码“x = x*x”或者“x *= x”;倘若自除运算指的是求某整型变量的倒数,也要老老实实地写以下代码“double y = 1.0/x”。求平方与求倒数的代码如下所示:

		// 没有“**”这个运算符,求平方还是按照常规写法
x *= x; // 也可以写成x = x*x
System.out.println("求平方 x="+x);
// “//”已经被用作注释标记了,求倒数也得按照常规写法,而且整数的倒数只能是小数
double y = 1.0/x; // 注意这里的1.0/x,由于x是整型数,因此1/x无法求得小数
System.out.println("求倒数 y="+y);

由于“++”和“--”从头到尾只有变量自身参与运算,并无其它的操作数,因此又被称作一元运算符。类似的一元运算符还有负号运算符“-”和正号运算符“+”,这两个符号其实也来源于数学,都放在数字前面,比如“-1”表示负一,“+1”表示正一。但在Java编程当中,变量前面的正负号概念有所不同,例如“-x”指的是对x做负号运算,“x = -x”等价于“x = 0-x”。倘若整型变量x原来是正值,则负号运算的结果为负值;但若x原来是负值,则负号运算的结果变为正值,也就是所谓的负负得正。至于“x = +x”等价于“x = 0+x”,显然正号运算的结果与原值相同,正值的正号运算结果仍为正值,负值的正号运算结果仍为负值,而非数学上的正号意义。要想验证上述的正负运算符,可运行下列代码观察测试结果。

		x = -x; // 等同于x=0-x
System.out.println("负数 x="+x);
x = +x; // 等同于x=0+x
System.out.println("正数 x="+x);

注意到上面的正负运算符直接放在变量之前,实际上“++”和“--”也允许放在变量前面,单独的“++x”等价于“x++”,单独的“--x”等价于“x--”。之所以特别强调“单独”二字,是因为一旦它们放到了其他语句之中,运算结果就将大不相同。譬如下述代码演示了二者之间的区别:

		int y1 = 7;
int z1 = y1++; // 后加加操作的优先级较低
System.out.println("z1="+z1);
int y2 = 7;
int z2 = ++y2; // 前加加操作的优先级较高
System.out.println("z2="+z2);

运行上面的演示代码,会得到下面的日志信息。

z1=7
z2=8

可见此时z1的数值不等于z2,究其原因,乃是前加加与后加加的运行机制差异所致。对于“int z1 = y1++;”,该语句在执行时会分解成下列两个步骤:先执行对z1的赋值操作,再执行对y1的自增操作。此时最终的运行步骤如同以下代码:

    int z1 = y1;
y1 = y1+1;

对于“int z2 = ++y2;”,该语句在执行时也会分解成下列两个步骤:先执行对y1的自增操作,再执行对z1的赋值操作。此时最终的运行步骤如同以下代码:

    y2 = y2+1;
int z2 = y2;

其实这种情况很好理解,计算机语言跟人类文字的书写顺序一样,都是从上到下、从左往右。定睛一看“x++”,果然先看到变量x,接着才看到自增运算++;回头再瞅“++x”,这下先看到自增运算,然后才看到变量x。同是书面文字,计算机语言和人类语言的语法逻辑大抵相同。
最后来个脑筋急转弯,现有变量z1值为7,变量z2值为8,那么且看下面代码的运算结果,变量z3的数值又该为何?有兴趣的朋友不妨一试。

    int z3 = ++z1+z2++;

  

Java开发笔记(十)一元运算符的技巧的更多相关文章

  1. Java开发笔记(三十二)字符型与整型相互转化

    前面提到字符类型是一种新的变量类型,然而编码实践的过程中却发现,某个具体的字符值居然可以赋值给整型变量!就像下面的例子代码那样,把字符值赋给整型变量,编译器不但没报错,而且还能正常运行! // 字符允 ...

  2. Java开发笔记(三十八)利用正则表达式校验字符串

    前面多次提到了正则串.正则表达式,那么正则表达式究竟是符合什么定义的字符串呢?正则表达式是编程语言处理字符串格式的一种逻辑式子,它利用若干保留字符定义了形形色色的匹配规则,从而通过一个式子来覆盖满足了 ...

  3. Java开发笔记(三十九)日期工具Date

    Date是Java最早的日期工具,编程中经常通过它来获取系统的当前时间.当然使用Date也很简单,只要一个new关键字就能创建日期实例,就像以下代码示范的那样: // 创建一个新的日期实例,默认保存的 ...

  4. Java开发笔记(四十)日期与字符串的互相转换

    前面介绍了如何通过Date工具获取各个时间数值,但是用户更喜欢形如“2018-11-24 23:04:18”这种结构清晰.简洁明了的字符串,而非啰里八唆依次汇报每个时间单位及其数值的描述.既然日期时间 ...

  5. Java开发笔记(一百四十二)JavaFX的对话框

    JavaFX的对话框主要分为提示对话框和文件对话框两类,其中提示对话框又分作消息对话框.警告对话框.错误对话框.确认对话框四种.这四种对话框都使用Alert控件表达,并通过对话框类型加以区分,例如Al ...

  6. Java开发笔记(一百三十四)Swing的基本对话框

    桌面程序在运行过程中,时常需要在主界面之上弹出小窗,把某种消息告知用户,以便用户及时知晓并对症处理.这类小窗口通常称作对话框,依据消息交互的过程,可将对话框分为三类:消息对话框.确认对话框.输入对话框 ...

  7. Java开发笔记(八十九)缓存字节I/O流

    文件输出流FileOutputStream跟FileWriter同样有个毛病,每次调用write方法都会直接写到磁盘,使得频繁的写操作性能极其低下.正如FileWriter搭上了缓存兄弟Buffere ...

  8. Java开发笔记(八十八)文件字节I/O流

    前面介绍了如何使用字符流读写文件,并指出字符流工具的处理局限,进而给出随机文件工具加以改进.随机文件工具除了支持访问文件内部的任意位置,更关键的一点是通过字节数组读写文件数据,采取字节方式比起字符方式 ...

  9. Java开发笔记(八十六)通过缓冲区读写文件

    前面介绍了利用文件写入器和文件读取器来读写文件,因为FileWriter与FileReader读写的数据以字符为单位,所以这种读写文件的方式被称作“字符流I/O”,其中字母I代表输入Input,字母O ...

  10. Java开发笔记(八十五)通过字符流读写文件

    前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...

随机推荐

  1. jsp页面的地址

    1. ${pageContext.request.contextPath}是JSP取得绝对路径的方法,等价于<%=request.getContextPath()%> . 也就是取出部署的 ...

  2. LIS的优化算法O(n log n)

    LIS的nlogn的优化:LIS的优化说白了其实是贪心算法,比如说让你求一个最长上升子序列把,一起走一遍. 比如说(4, 2, 3, 1, 2,3,5)这个序列,求他的最长上升子序列,那么来看,如果求 ...

  3. layui 表格内容显示更改

    在cole 中使用temple 属性进行修改 例: table.render({ elem: '#messageTable' ,id: 'search_table_mId' ,height: 500 ...

  4. [译文]Domain Driven Design Reference(六)—— 提炼战略设计

    本书是Eric Evans对他自己写的<领域驱动设计-软件核心复杂性应对之道>的一本字典式的参考书,可用于快速查找<领域驱动设计>中的诸多概念及其简明解释. 其它本系列其它文章 ...

  5. new Date()设置日期在IOS的兼容问题

    一般这样创建一个日期变量 var d = new Date("2017-08-11 12:00:00"); 发现在iOS中不兼容,返回valid Date. IOS中不支持 - 连 ...

  6. 【计算机篇】Office 2016 for Mac 安装和破解教程

    免责声明 请亲们支持正版.这教程旨在分享,供参考. 为啥写这篇文章 对于大多数使用 Mac 的用户而言,虽然有苹果自家的办公软件,但功能少,用起来不舒服.而 Offer 2016 版的需要登录激活购买 ...

  7. Java开发快速上手

    Java开发快速上手 前言 1.我的大学 2.对初学者的建议 3.大牛的三大特点 4.与他人的差距 第一章 了解Java开发语言 前言 基础常识 1.1 什么是Java 1.1.1 跨平台性 1.2 ...

  8. [Swift]LeetCode256.粉刷房子 $ Paint House

    There are a row of n houses, each house can be painted with one of the three colors: red, blue or gr ...

  9. Redis 设计与实现 (九)--Lua

    EVAL script numkeys key [key ...] arg [arg ...] script:     你的lua脚本 numkeys:  key的个数 key:           ...

  10. scala的reduce

    spark 中的 reduce 非常的好用,reduce 可以对 dataframe 中的元素进行计算.拼接等等.例如生成了一个 dataframe : //配置spark def getSparkS ...