美文网首页
long i = 1000*60*60*24*30;由于符号拓展

long i = 1000*60*60*24*30;由于符号拓展

作者: 晨钟初磬 | 来源:发表于2018-11-15 12:37 被阅读0次

    案例描述

    同事使用Date类的getTime方法减去30天的毫秒数,反转成Date,发现日期没有像预期那件月份减少一个月,反而增加了。

    代码如下:

    Date now = new Date();
    System.out.println(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(now.getTime() - 1000*60*60*24*30)));
    

    输出结果:

    20181205041335
    

    反编译之:


    反编译结果

    案例分析

    1000*60*60*24*30 = 2592000000;
    Integer.MAX_VALUE=2147483647;
    30天这个毫秒数值已经溢出。
    从反编译结果来看,这个数被解释成long,并且是个负数,所以日期才会不减反增。那么,java对这个整数溢出数怎么个处理逻辑呢?

    1. 字面值默认类型为int型0x9A7EC800
    2. 由于getTime函数结果是long型的,会有一个promotion,这个字面值由于是负值,会被符号位补1拓展;

    证明
    0x9A7EC800拓展成8字节为0xFFFFFFFF9A7EC800
    0xFFFFFFFF9A7EC800取反为0x00000000658137ff
    0x658137ff+1 =0x65813800
    (0xFFFFFFFF9A7EC800)补 = (-0x65813800)原 = -1702967296
    与反编译中constant pool中的数值一致。

    反编译得到的值

    反思

    对于大字面值,需要指定类型:


    thinking in java中的建议

    L代表long,F代表float,D代表double


    摘自于thinking in java

    相关文章

      网友评论

          本文标题:long i = 1000*60*60*24*30;由于符号拓展

          本文链接:https://www.haomeiwen.com/subject/kznefqtx.html