Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 703|回复: 0

Java篇——运算顺序的详细挖掘

  [复制链接]

该用户从未签到

发表于 2016-5-17 16:58:33 | 显示全部楼层 |阅读模式
3Java金币
java——运算顺序的详细挖掘
Java 运算中,存在一些关系到顺序的计算,这些计算顺序在 C / C++语言中是不确定的,并且最后的结果值也没有保证。不过, Java 经过编译之后,生成的是与平台无关的字节码,并且交互对象为 Java 虚拟机,与底层的硬件环境无关。因此,这些运算结果在 Java 中是确定的。
从左向右的计算顺序
C / C++不同的是,在 Java 中,表达式的计算与结果是确定的。不受硬件环境的影响。例如,一个在 C / C++中比较常见例子:
  1. int i = 5;
  2. int j = (i++) + (i++) + (i++);
复制代码

C / C++中,变量 i j 的值是不确定的,根据不同的开发环境,结果也不相同。例如,在 Turbo C 中, i 的值为 8 j 的值为 15,而在 VC 中, i 的值为 8 j 的值为 18。在 Java中, i j 的值是确定的, i 8 j 18
Java 中,操作数的计算顺序是从左向右的也就是首先会计算左侧的操作数,然后再计算其右侧的操作数。例如:
  1. int a = 3;
  2. int b = a + (++a) + (a = 1) + a;
复制代码

执行这两个语句之后, a 的值为 1 b 的值为 9。因为 Java 就是从左向右进行计算的,故最后(即最右侧)一条修改 a 值的表达式为:
  1. a = 1
复制代码

而第 2 条语句也就是:
  1. int b = 3 + 4 + 1 + 1;
复制代码

操作数从左向右的计算规则与运算符的结合性无关,就算运算符是由右向左结合的,也会在运算之前先确定左侧的操作数,请看下面的程序。
【例】 操作数的确定。
  1. package chapter2;
  2. 2.
  3. 3. import java.util.Arrays;
  4. 4.
  5. 5. public class Order {
  6. 6. public static void main(String[] args) {
  7. 7. int a[] = new int[] {
  8. 8. 0, 0, 0, 0, 0, 0
  9. 9. };
  10. 10. int i = 1;
  11. 11. a[++i] = i++;
  12. 12. System.out.println("i=" + i);
  13. 13. System.out.println(Arrays.toString(a));
  14. 14. int j = 3;
  15. 15. a[j] = j = 4;
  16. 16. System.out.println("j=" + j);
  17. 17. System.out.println(Arrays.toString(a));
  18. 18. int b[] = new int[] {
  19. 19. 9, 9, 9, 9, 9, 9
  20. 20. };
  21. 21. int k = 5;
  22. 22. int c[] = a;
  23. 23. a[--k] = (a = b)[k];
  24. 24. System.out.println("k=" + k);
  25. 25. System.out.println(Arrays.toString(a));
  26. 26. System.out.println(Arrays.toString(b));
  27. 27. System.out.println(Arrays.toString(c));
  28. 28. }
  29. 29.}
复制代码

程序运行结果如下:
  1. i=3
  2. [0, 0, 2, 0, 0, 0]
  3. j=4
  4. [0, 0, 2, 4, 0, 0]
  5. k=4
  6. [9, 9, 9, 9, 9, 9]
  7. [9, 9, 9, 9, 9, 9]
  8. [0, 0, 2, 4, 9, 0]
复制代码

你预测正确了吗?对于程序第 11 行:
  1. a[++i] = i++;
复制代码

虽然赋值运算符是从右向左结合的,但是操作数的确定是从左向右的,也就是在赋值操作发生前,首先会确定左侧的操作数, i 的值为 1 ++i 的值就是 2,因此,左侧的操作数是 a[2],因此,这条语句就相当于:
  1. a[2] = 2;
复制代码

然后 i 的值再加 1,值为 3
15 行的赋值语句:
  1. a[j] = j = 4;
复制代码

也是同样的道理,首先确定左侧操作数,j 的值为 3,也就是 a[3],这相当于:
  1. a[3] = j = 4;
复制代码

赋值之后, j a[3]的值都是 4
同样,第 23 行的语句:
a[--k] = (a = b)[k];
k 的值是 5,这就相当于:
  1. --k;
  2. int[] temp = a;
  3. a = b;
  4. temp[4] = b[4];
复制代码

然后,原数组 a[4](也就是后来的 c[4])的值改变。
复合运算符
我们知道,复合运算符可以自动将右侧运算的结果类型转换为左侧操作数的类型。例如如下的代码:
  1. byte b = 1;
  2. b = b + 1; //错误
  3. b += 1; //正确
复制代码

因为常量 1 int 类型,所以右侧的结果是 int 类型,不能赋值给一个 byte 类型的变量,但
是使用复合运算符( +=)是可以的,第 3 条语句相当于:
  1. b = (byte)(b + 1);
复制代码

除此之外,复合运算符也有上述的性质,即遵循操作数从左向右计算的原则,也就是说,在执行赋值操作之前,首先会确定左侧的操作数。
【例】 复合运算符。
  1. 1.        package chapter2;
  2. 2.
  3. 3. import java.util.Arrays;
  4. 4.
  5. 5. public class Order2 {
  6. 6. public static void main(String[] args) {
  7. 7. int a = 10;
  8. 8. a += ++a;
  9. 9. System.out.println("a=" + a);
  10. 10. int[] array = new int[] {
  11. 11. 8, 9, 10
  12. 12. };
  13. 13. int b = 1;
  14. 14. array[b] *= b = 2;
  15. 15. System.out.println("b=" + b);
  16. 16. System.out.println(Arrays.toString(array));
  17. 17. }
  18. 18.}
复制代码

由于有了上面的讲解,这个程序的运行结果应该不难想象了,如下:
  1. a=21
  2. b=2
  3. [8, 18, 10]
复制代码

总之,运算前会先将左侧的操作数保存起来,左侧的操作数不会受到其右侧表达式的影响而造成改变。
总结:
1. Java 语言中,操作数的计算顺序是从左向右的,即使运算符是从右向左结合的也是
如此。
2. C / C++等语言不同, Java 的运算结果受硬件环境的影响很小,计算方式也是确定的。
举一反三
在参数传递的过程中,是否也符合本话题讲述的规则呢?例如下面的程序:
  1. 1.package chapter2;
  2. 2.
  3. 3. public class Order3 {
  4. 4. public static void main(String[] args) {
  5. 5. Order3 order = new Order3();
  6. 6. int i = 10;
  7. 7. order.test(i, ++i, i = 2);
  8. 8. order.test(i = 5, i++, i);
  9. 9. }
  10. 10.
  11. 11. public void test(int x, int y, int z) {
  12. 12. System.out.println(x);
  13. 13. System.out.println(y);
  14. 14. System.out.println(z);
  15. 15. }
  16. 16.}
复制代码

结果是多少呢?自己试试看吧。
本文出自柠檬派http://www.lemonpai.com   请务必保留此出处 ,否则将追究法律责任!

回复

使用道具 举报

该用户从未签到

发表于 2016-5-17 22:16:09 | 显示全部楼层
呵呵,好帖一定要顶,支持












流行  原创  翻唱  怀旧 摇滚 嘻哈
回复

使用道具 举报

该用户从未签到

发表于 2016-5-18 00:43:25 | 显示全部楼层
能发这么好的帖子,太谢谢了













让这一切灰飞烟灭吧       
滚动       
化妆       
美文共赏摘抄500字       
新闻排行       
塞尔哈特古尔皮纳尔       
奥古斯托费尔南德斯       
体育       
教师培养       
互联网       
暴戾冥思者       
春季养生中医小妙招       
奇闻趣事       
女人养生美容       
养生菜谱大全及做法       
戒色养生的心得体会       
夏季养生论文       
美文精选摘抄       
本校课程       
导引养生功
回复

使用道具 举报

该用户从未签到

发表于 2016-5-19 06:09:51 | 显示全部楼层
这个可以回,这个真得回!













美文200字       
汽车检测标准       
商人的黑丹气功牌       
瘀血体质的养生原则       
爱情美文摘抄300字       
月兔之请       
短篇美文       
女性健康养生知识       
汇众汽车       
校园新闻       
胡安曼努埃尔奥蒂兹       
大地祝福肩甲       
珍爱生命美文       
埃杜瓦尔多达席尔瓦       
高中英语美文       
帅哥       
活力秀场       
羯磨拳套阶段       
中医养生学心德       
柏林奥林匹克体育场
回复

使用道具 举报

该用户从未签到

发表于 2016-5-19 11:07:45 | 显示全部楼层
回复

使用道具 举报

该用户从未签到

发表于 2016-5-19 11:34:36 | 显示全部楼层
行,有意义,我顶 谢谢您了












居家   宠物  聚会   美食   记录  法制
回复

使用道具 举报

该用户从未签到

发表于 2016-5-20 03:04:17 | 显示全部楼层
辛苦辛苦,谢谢了~~













社团活动       
中国军事       
媒体报道       
美女       
文史       
情感999美文       
8090爱情美文       
聚集点标识       
紫水晶戒指       
绿色奥运行动计划       
军事历史       
李昌镐围棋基础训练       
美文摘抄加赏析200字       
垂直电商       
韩氏专业养生减肥       
反震程度       
秋冬季如何养生       
短篇美文摘抄       
圣安东尼奥马刺队       
美发
回复

使用道具 举报

该用户从未签到

发表于 2016-5-20 03:22:28 | 显示全部楼层
我来看看!谢谢













汽车指标查询       
破旧的棉布护肩       
修心养生相关的文章       
汽车行业分析       
魅族       
帅哥       
汽车行业       
美国国家篮球协会       
兹拉坦柳比扬基奇       
明星风尚       
欧美明星       
生化研究室       
教师频道       
大地之握       
奥利维拉莫斯卡维德       
美文经选       
中医四季养生       
穿越耽美文       
语文美文摘抄       
励志美文300字
回复

使用道具 举报

该用户从未签到

发表于 2016-5-21 22:01:48 | 显示全部楼层
说的好,一定回复~













3D打印       
生活       
强力剃骨刀       
汽车行业前景       
HTC       
娱乐名人       
野史秘闻       
埃迪兹巴蒂亚罗格鲁       
解密档案       
学科资料       
新闻综合名医话养生       
数字电视       
五行经络养生       
部落酋长       
网站地图       
健康养生食谱       
破旧的亚麻披肩       
汽车标志       
特夫菲克艾尔迪奥克       
奥林匹克主体育场
回复

使用道具 举报

该用户从未签到

发表于 2016-5-24 09:18:01 | 显示全部楼层
顶也~~~













未接之谜       
福田汽车网       
蚩祖血刃       
物流       
四通一达       
初中美文摘抄300字       
汽车改装配件       
英格兰足球超级联赛       
关于健康养生的知识       
无龄的养生智慧       
霍普曼杯混合团体赛       
沙里姆斯塔德迈尔       
学生天地       
克里斯托弗格雷高里       
学生天地       
描写秋天的美文散文       
赫顿玛尔贵族布鞋       
化妆       
乐生活       
十万火急
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2024-4-25 10:20 , Processed in 0.431598 second(s), 32 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表