+=与=..+..的区别(转自http://www.ticmy.com/?p=285)
来源:互联网 发布:海康ntp服务器地址端口 编辑:程序博客网 时间:2024/06/06 01:23
在书本中,课堂上,关于a+=b大都说等价于a = a+b,其实不然,+=中包含着更多的东西。
在继续之前,来温故一点基础(为简单起见,只说整数)。
1、做基本运算(如+、-、*、/、<<、>>、>>>、~、^等),当两个操作数的类型是byte,short,char,int之一的时候,结果的类型是int;
2、做整数基本运算时,当一个操作数是long,结果是long;
3、不加任何修饰的整数字面值默认就是int类型。
下面对上面的几点举例说明:
short
s1 =
1
;
//OK
short
s2 = s1 +
1
;
//ERROR
上面的第一句1整形字面值,它的类型是int,为什么可以直接赋值给short呢?因为字面值都是常量,编译器能很容易的检测出它到底在不在short所能表示的值的范围内。当写成short s1 = 32768的时候,编译就知道short容不下32768了,就会报错。
而对于第二句,s1是short类型,1是int类型,结果是int类型,自然不能自动赋值给short类型的s2了,因为有潜在的高位有效值被截断的风险。可能会有人想,上面s1已经赋值了一个字面值,对于下面的s2,编译器应该也可以计算出它的值啊。如果s1是final的,确实会这样,但s1是变量,编译器是无法预测它会不会在运行期改变的,即使它可能不会改变。
再来一个,计算一年有多少毫秒,粗心的人可能这么写:
long
mills =
365
*
24
*
60
*
60
*
1000
;
明眼人一看就有问题了,后面的几个数字都是int类型,计算后结果还是int类型,再将其转换成long类型,等效于以下的逻辑:
int
tmp =
365
*
24
*
60
*
60
*
1000
;
long
mills = tmp;
出计算结果的时候数据已经溢出了,再将其转换成long,依然得不到正确的结果,这样的计算很常见,也很容易被人疏忽,纠正它很容易,只要指定一个数为long类型即可:
long
mills =
365
*
24
*
60
*
60
* 1000L;
开始简短的正题,如下的两段代码的区别:
short
s =
1
;
s = s +
1
;
//error
short
s =
1
;
s +=
1
;
//ok
第一段代码上面已经有分析了,它通不过编译;来看看第二段,首先它能通过编译,来看看编译后的字节码(javap -c 类名)是什么样的吧:
0: iconst_11: istore_12: iload_13: iconst_14: iadd5: i2s6: istore_1
指令0,1做了short s = 1操作,指令2,3,4做了s+1的操作,第5条是关键,做了一个强制转换,将int转换为short,第6条将强制转换的结果存回变量s。
如果s是int类型呢?
int
s =
1
;
s +=
1
;
//ok
对应的字节码:
0: iconst_11: istore_12: iinc 1, 1
它直接等价于i++操作了,和以下代码生成的字节码是一样的:
int
s =
1
;
s++;
当s += 2的时候,指令为iinc 1, 2,这里是没有强制转换的。
综上可以看到(其中type为byte,short,char,int之一,value可为变量可为常量,类型可为byte,short,char,int,float,double,long):
type s = value;
s += ovalue;
//ok
逻辑上等价于(说逻辑上是因为type为int的时候并不存在强制转换,但结果是相同的):
type s = value;
s = (type)(s + ovalue);
- +=与=..+..的区别(转自http://www.ticmy.com/?p=285)
- java中i=i++问题分析 source:http://www.ticmy.com/?p=43
- C++中函数重载、隐藏、覆盖和重写的区别 转自:http://www.bijishequ.com/detail/277975?p=
- 很好的一些开源项目(转自:http://www.uuroid.com/?p=135)
- Qt全局热键(windows篇)(转自:http://www.cuteqt.com/blog/?p=2088)
- Verilog中wire与reg类型的区别(转载自http://www.cnblogs.com/farbeyond/p/5204586.html)
- 解决跨域iframe自适应高度(转自:http://www.lzlu.com/blog/?p=692)
- http://www.yule4.com/?p=191
- Function类的重要方法call()与apply() http://www.xncat.com/?p=1568
- 用PXE引导调用kickstart安装CentOS 5(转自:http://www.shunqiziran.com/?p=97)
- 用PXE引导调用kickstart安装CentOS 5 (转自http://www.shunqiziran.com/?p=97)
- mysql data文件夹下的ibdata1 文件作用(转http://www.doremc.com/?p=131)
- 实时视频应用之QoS关键技术分析 转自:http://www.aiweibang.com/m/detail/104476372.html?from=p 随着WebRTC标准的逐步推广,实
- grep, sed 与 awk 转自 http://www.cnblogs.com/moveofgod/p/3540575.html
- http://www.cuteqt.com/blog/?p=791
- block使用http://www.cnbluebox.com/?p=255
- http://www.jianshu.com/p/584707554ed7?ref=myread
- 技术博客全线迁移到http://www.ticmy.com/
- activi参考网址
- WebRTC源代码探索之旅——多线程篇-1
- 最小路径覆盖_zoj1525_最小路径覆盖+水
- MD5加密工具类
- QT中QWidget、QDialog与QMainWindow的区别
- +=与=..+..的区别(转自http://www.ticmy.com/?p=285)
- Java定时任务2:Jcrontab介绍
- 通过Android Studio查看SDK源码
- Android热修复实现
- 如何创建一个用户看不到的窗口。
- Oracle 快照初次使用
- WebRTC源代码探索之旅——多线程篇-2
- 强制类型转换
- 给UICollectionViewCell绑定手势 long press举例