2013-12-10 31 views
8

对于下面的代码:Java的日期 - 长VS INT

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 

为什么它们有什么不同?

回答

15

由于第二值是使用integer不是long和溢出。

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

这是因为在第二个例子中,这两个值都是整数。 int * int = int。它只是变得晋升为长,如果一个或多个值乘以(或与此有关的任何其他数学运算)是一个漫长的。有没有“神奇”检测溢出并执行推广为您服务。

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

您还可以在更细微的地方看到过 - 例如:

long l; 
int x,y; 

long result = l+x*y; 

即使结果和L都长,X * Y仍在为整数,因为乘法先所做的一切。即使x和y分别适合32位整数,如果两个产品没有你碰到溢出的情况。解决方法是,以确保其在您遇到的溢出风险的最早的点转换为长 - 例如:

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

@Vlad:那'L'在第一个参数是显著,你看。尝试'System.out.println(1386633600 * 1000)'看看你得到了什么...... –

+2

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