short的日常梗

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011724770/article/details/84474294

首先上问题:

public static void main(string[] args){
          short s=1;
          s=s+1;
          s+=1;
          s++;
          system.out.println(s);
}
 

一个很普通的赋值,和值的运算,但是short运用的非常少见,所以这个乍一看是没问题的,但其实问题很大....因为s=s+1会出错。

为什么呢?

让我们看看j从ava的创造者视角看这个问题是怎么样的?引用资料java语言规范(JLS)

1.JLS(中文版第三版)5.2 赋值转换

    1)当把表达式的值赋予一个变量时,就会发生赋值转换:必须把表达式的类型转换为变量的类型;

    2)如果表达式是类型byte,short,char,int的常量表达式,则如果变量类型是byte,short,char,并且常量表达式的值在变量的类型中是可以表示的,那么就执行窄化转换 (narrowing conversion),如果不能通过赋值环境中允许的转换把表达式的类型转换成变量的类型,那么编译时会报错。这个可以用来解释s=1,为何将int赋值给short不会报错

    3)s=s+1为什么会报错?这里我没有看JLS,因为s=s+1,左边有变量参与,编译器在无法分析出该变量的值是什么,因为s为变量,其值不确定无法确定s+1是否超出short范围,为了防止进行类型转换时丢失精度,所以编译器直接当成无法确定来处理,报错了事。so,当有变量为byte,short,char时,编译器就是这么干的。需要知道的是在编译期间,虚拟机只做语法检查,而不会进行计算动作,也就是说虚拟机不会对s+1是否查出s的范围而进行一次计算判断。

    4)s++呢?对于后缀++,JLS说在s+1时也要执行二元数值提升,即一个操作数是double,那么把另一个操作数转化成double;否则一个操作数是float,那么把另一个操作数转化成float;否则一个操作数是long,那么把另一个操作数转化成long;否则两个都转化为int(JLS中文三版5.6.2);如有必要将s+1的和进行窄化转换,即将s+1做强制转换(short)(s+1)然后赋给s。(JLS中文三版15.15.1)

    5)最后s+=1,JLS中文三版15.26.2说对于组合运算符形如E1 op=E2的组合赋值表达式等价于E1=(T)((E1)op(E2))其中T为E1的类型,例如s+=1等价于s=(short)(s+1)。

猜你喜欢

转载自blog.csdn.net/u011724770/article/details/84474294