Java日期从毫秒到整数

Java日期从毫秒到整数,java,time,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

对于以下代码:

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)));
    }

}
我得到以下输出:

10-12-2013
24-12-1969

为什么它们不同?

因为第二个值使用的是
整数
而不是
长的
,并且已溢出

如果在任一常数的末尾添加一个L,它将切换为使用
long
值,并且差值将消失

这是因为在第二个示例中,两个值都是整数。int*int=int。只有当一个或多个相乘的值(或任何其他数学运算)是长值时,才会将其提升为长值。没有“魔法”可以检测溢出并为您进行升级

即使执行了
long x=int*int
操作,它仍将以32位进行乘法运算,然后将结果转换为64位进行赋值

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

long l;
int x,y;

long result = l+x*y;
long result = l+((long)x)*y;
尽管result和l都很长,但x*y仍然作为整数进行,因为乘法是先进行的。即使x和y分别适合32位整数,如果两者的乘积不匹配,您也会遇到溢出情况。解决方法是确保在您遇到溢出风险的最早点将其转换为long,例如:

long l;
int x,y;

long result = l+x*y;
long result = l+((long)x)*y;

@弗拉德:你看,第一个参数中的
L
很重要。尝试
System.out.println(1386633600*1000)
看看你得到了什么…@Vlad java编译器不进行类型推断,类型检查的方式与你想象的相反:它首先修复表达式的类型,然后为它选择合适的方法。在这种情况下,它有一个
int
,因此
Date(long)
构造函数是最合适的。(方法是否完全没有重载并不重要。)