Java开发笔记(十)一元运算符的技巧
前面讲到赋值运算符的时候,提到“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开发笔记(十)一元运算符的技巧的更多相关文章
- Java开发笔记(三十二)字符型与整型相互转化
前面提到字符类型是一种新的变量类型,然而编码实践的过程中却发现,某个具体的字符值居然可以赋值给整型变量!就像下面的例子代码那样,把字符值赋给整型变量,编译器不但没报错,而且还能正常运行! // 字符允 ...
- Java开发笔记(三十八)利用正则表达式校验字符串
前面多次提到了正则串.正则表达式,那么正则表达式究竟是符合什么定义的字符串呢?正则表达式是编程语言处理字符串格式的一种逻辑式子,它利用若干保留字符定义了形形色色的匹配规则,从而通过一个式子来覆盖满足了 ...
- Java开发笔记(三十九)日期工具Date
Date是Java最早的日期工具,编程中经常通过它来获取系统的当前时间.当然使用Date也很简单,只要一个new关键字就能创建日期实例,就像以下代码示范的那样: // 创建一个新的日期实例,默认保存的 ...
- Java开发笔记(四十)日期与字符串的互相转换
前面介绍了如何通过Date工具获取各个时间数值,但是用户更喜欢形如“2018-11-24 23:04:18”这种结构清晰.简洁明了的字符串,而非啰里八唆依次汇报每个时间单位及其数值的描述.既然日期时间 ...
- Java开发笔记(一百四十二)JavaFX的对话框
JavaFX的对话框主要分为提示对话框和文件对话框两类,其中提示对话框又分作消息对话框.警告对话框.错误对话框.确认对话框四种.这四种对话框都使用Alert控件表达,并通过对话框类型加以区分,例如Al ...
- Java开发笔记(一百三十四)Swing的基本对话框
桌面程序在运行过程中,时常需要在主界面之上弹出小窗,把某种消息告知用户,以便用户及时知晓并对症处理.这类小窗口通常称作对话框,依据消息交互的过程,可将对话框分为三类:消息对话框.确认对话框.输入对话框 ...
- Java开发笔记(八十九)缓存字节I/O流
文件输出流FileOutputStream跟FileWriter同样有个毛病,每次调用write方法都会直接写到磁盘,使得频繁的写操作性能极其低下.正如FileWriter搭上了缓存兄弟Buffere ...
- Java开发笔记(八十八)文件字节I/O流
前面介绍了如何使用字符流读写文件,并指出字符流工具的处理局限,进而给出随机文件工具加以改进.随机文件工具除了支持访问文件内部的任意位置,更关键的一点是通过字节数组读写文件数据,采取字节方式比起字符方式 ...
- Java开发笔记(八十六)通过缓冲区读写文件
前面介绍了利用文件写入器和文件读取器来读写文件,因为FileWriter与FileReader读写的数据以字符为单位,所以这种读写文件的方式被称作“字符流I/O”,其中字母I代表输入Input,字母O ...
- Java开发笔记(八十五)通过字符流读写文件
前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...
随机推荐
- 推荐自学JAVA开发的三本书
---------------------------------------------------------------------------------------------------- ...
- 【react】---手动封装一个简易版的redux
export let createStore = (reducer)=>{ //定义默认的state let state; //定义默认的action let actionTypes = &qu ...
- d3.js,初遇
接触d3完全是由兴趣所致,废话不多说看代码: var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];这是这个图所需要的数据,其实这个柱状图最初不长这 ...
- unittest各个组件之间的关系
各个组件的含义: TestCase:测试用例,测试用例里面会有很多测试方法,是单元测试中最小维度的测试行为. TestSuite:测试套件,是测试用例的集合. TestFixure:测试固件,测试准备 ...
- 【安富莱专题教程第4期】SEGGER的J-Scope波形上位机软件,HSS模式简单易用,无需额外资源,也不需要写目标板代码
说明:1.在实际项目中,很多时候,我们需要将传感器或者ADC的数值以波形的形式显示.通常的解决办法是用串口上位机,USB接口上位机或者MDK的逻辑分析仪功能,使用这三种方式都比较繁琐.本期专题为大家讲 ...
- 版本号严格遵守semver语义化标准
地址:http://semver.org/lang/zh-CN/?spm=a219a.7629140.0.0.GUJMXE 语义化版本 2.0.0 摘要 版本格式:主版本号.次版本号.修订号,版本号递 ...
- Java部署项目命令学习小结
前言: 暂无 零:java -h 和很多linux命令一样,我们第一步先通过“java -h”命令查看java命令的使用语法,其输出如下 [root@wxapp203 basesoft]# java ...
- Kubernetes系列之监控Metres-server实战篇
本次系列使用的所需部署包版本都使用的目前最新的或最新稳定版,安装包地址请到公众号内回复[K8s实战]获取 介绍 从 Kubernetes 1.8 开始,Kubernetes 通过 Metrics AP ...
- React中的通讯组件
1.父传子: 传递:当子组件在父组件中当做标签使用的时候,给当前子组件绑定一个自定义属性,值为需要传递的数据 接收:在子组件内部通过this.props进行接收 2.子传父 传 ...
- Spark中SQL列和并为一行
在使用数据库的时候,需要将查询出来的一列按照逗号合并成一行. 原表名字为 TABLE ,表中的部分原始数据为: +---------+------------------------+ | BASIC ...