• +=与=..+..的区别


    +=与=..+..的区别

    分类:java基础日期:2012-09-28作者:ticmy

     
     

    在书本中,课堂上,关于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_1
    1:   istore_1
    2:   iload_1
    3:   iconst_1
    4:   iadd
    5:   i2s
    6:   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_1
    1:   istore_1
    2:   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);
  • 相关阅读:
    JVM优化系列之一(-Xss调整Stack Space的大小)
    被kill问题之2:Docker环境下Java应用的JVM设置(容器中的JVM资源该如何被安全的限制)
    docker的坑
    docker容器内存占用 之 系统cache,docker下java的内存该如何配置--temp
    查看docker容器的内存占用
    使用Java监控工具出现 Can't attach to the process
    使用docker查看jvm状态,在docker中使用jmap,jstat
    在Docker中监控Java应用程序的5个方法
    HDU2552 三足鼎立 【数学推理】
    C++面向对象模型
  • 原文地址:https://www.cnblogs.com/01picker/p/4306342.html
Copyright © 2020-2023  润新知