来自millis的Java Date - long vs int

Vla*_*lad 8 java time

对于以下代码:

import java.text.SimpleDateFormat;
import java.util.Date;

public class TestMain {

    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
        System.out.println(sdf.format(new Date(1386633600000L)));
        System.out.println(sdf.format(new Date(1386633600 * 1000)));
    }

}
Run Code Online (Sandbox Code Playgroud)

我得到以下输出:

10-12-2013
24-12-1969
Run Code Online (Sandbox Code Playgroud)

他们为什么不同?

Tim*_*m B 15

因为第二个值是使用integera long而不是溢出.

如果在任一常量的末尾添加一个L,它会将其切换为使用long值,差异将消失.

这是因为在第二个例子中,两个值都是整数.int*int = int.如果一个或多个值乘以(或任何其他数学运算)很长,它只会被提升为long.没有"魔法"可以检测溢出并为您进行促销.

即使你这样做,long x = int*int它仍将以32位进行乘法运算,然后将结果转换为64位进行赋值.

您也可以在更微妙的地方看到这一点 - 例如:

long l;
int x,y;

long result = l+x*y;
Run Code Online (Sandbox Code Playgroud)

即使结果和l都很长,x*y仍然以整数形式完成,因为乘法是先完成的.即使x和y分别适合32位整数,如果两者的乘积不存在溢出情况.修复方法是确保在遇到溢出风险的最早点将其转换为long - 例如:

long result = l+((long)x)*y;
Run Code Online (Sandbox Code Playgroud)

  • @Vlad java编译器不进行类型推断,类型检查的方式与你想的不同:它首先修复表达式的类型,然后为它选择合适的方法.在这种情况下,它有一个`int`,因此`Date(long)`构造函数是最合适的.(如果方法根本没有超载也没关系.) (2认同)