黑马程序员技术交流社区

标题: Java中x=x+1 与x+=1 的一点区别 [打印本页]

作者: xbs783    时间: 2016-11-6 22:01
标题: Java中x=x+1 与x+=1 的一点区别
首先来看下面两行代码:

short s1 = 1;  
s1 = s1 + 1;  
对于稍微有点Java经验的人来说,这个是非常简单的问题,他们肯定会说 这样是无法通过编译的。
首先,因为short类型是16位的,而int类型是32位的,在进行(s1+1) 运算时,自动将s1提升到32位,然后与i相加,

得到的结果是32位的,而此时s1=s1+1; 必然报错,因为这样会丢失2个字节的精度,这是不容许的。但是你可以执行强转:

s1=(short)(s1+1); 这样就没问题了.

现在我们再看下面这两行代码:


short s1 = 1;  
s1 +=1;  
许多程序员都会认为这里的表达式(s1 +=1)只是上面表达式(s1 = s1 + 1)的简写方式,至少以前我是这样认为的。但是这并不十分准确。

这两个表达式都被称为赋值表达式。开头那条语句使用的是简单赋值操作符(=),而这里这条语句使用的是复合赋值操作(+=)。

Java语言规范中讲到,复合赋值 E1 op= E2等价于简单赋值E1 = (T)((E1)op(E2)  其中T是E1的数据类型,op为操作符.

这种类型转换或者是一个恒等转换,或者是一个窄化转换.

换句话说,复合赋值表达式自动地将它们所执行的计算的结果转型为其左侧变量的类型。如果结果的类型与该变量的类型相同,那么这个转型不会造成任何影响。然而,如果结果的类型比该变量的类型要宽,那么复合赋值操作符将悄悄地执行一个窄化原始类型转换。

但是我们让JVM自动的为我们进行窄化转换这样好吗?我们来看下,下面这个问题

short s1=Short.MAX_VALUE;//32767  
s1+=1;  
System.out.println(s1);  
你可能会认为结果是32768,但是你一运行就会发现它会打印出:-32768,此时你也许幡然醒悟,原来我们丢失了精度,所以我们在用复合

赋值操作(+=)的时候要特别注意,这时它会窄化原始类型转换(即会丢失精度)。
作者: 15626187339    时间: 2016-11-6 22:18
学习 学习
作者: 明月已驻人何在    时间: 2016-11-6 22:38
毕竟自带强转

作者: yeshusheng    时间: 2016-11-6 22:50
+= ,-=,*=,/=都自带强转
作者: 猎魔时代    时间: 2016-11-6 22:53
后者可以自动强转

作者: 猎魔时代    时间: 2016-11-6 22:55
yeshusheng 发表于 2016-11-6 22:50
+= ,-=,*=,/=都自带强转

又学到了

作者: Artemis    时间: 2016-11-6 23:29
感谢分享 学习了
作者: 袁志娜    时间: 2016-11-6 23:36

作者: 小牛想成为大牛    时间: 2016-11-7 00:14
设计到转换的问题都要注意下范围吧,,学习到啦
作者: zgang    时间: 2016-11-7 18:47
byte b1 = 1;
byte b2 = 2;
byte b3 = (byte)(b1+b2)
byte b = 1+2;
常量优化机制
作者: L10052108    时间: 2016-11-9 14:24
看样子,楼主对 java的运算很熟悉,我是一个菜鸟,考试时候遇到一个难题,想了很久
还是不是很明白,楼主可以帮我讲一下吗?下面是代码
[AppleScript] 纯文本查看 复制代码
public class test {
        public static void main(String[] args) {
                int a = 10;
                int b = (a++) + (++a) + (a * 10);
                System.out.println(b);
        }

}
一个数的自增,或则自减。可是遇到多个,我就有点儿不明白了结果:142?






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2