为什么COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30为负?

时间:2014-07-31 07:31:50

标签: java long-integer

final long COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30;

输出:-1702967296

有人告诉我在1000以后放L?它的工作原理

final long COOKIE_TIMEOUT = 1000L * 60 * 60 * 24 * 30;

输出:2592000000

为什么会这样?

8 个答案:

答案 0 :(得分:6)

整数溢出,放1000L,这将强制进行长时间转换

<强>更新 稍微长一点的解释:

例如,如果你只做1000 * 10,java会将它们视为整数。 在原始代码中,您正在进行溢出的整数计算,然后将溢出的值转换为long。

但是如果你把L放在第一个数字后面,那么java会把它们视为long(最左边的操作数定义了粒度),你就不会出现溢出。

另一个例子是这段代码:

double a = 5 / 2;
double b = 5d / 2;

System.out.println(a + " != " + b);

这将打印出来:

2.0 != 2.5

为什么呢?在计算a时,java将5和2视为整数并进行整数除法,然后将结果转换为double。在计算b时,你告诉java 5实际上是双精度,它执行双重除法。

答案 1 :(得分:3)

虽然COOKIE_TIMEOUTlong,但右手表达式由整数组成,因此其类型为int。结果大于导致溢出的Integer.MAX_VALUE。当表达式中至少有一个操作数属于较高类型(例如long)时,整个表达式变为long并且不会发生溢出。

这是您在第二个示例中执行的操作,当您在其中一个数字常量之后添加L修饰符时。此常量变为long,因此表达式也变为long

答案 2 :(得分:3)

此行为是由Java编译器选择的表达式的类型引起的。在这种情况下,它看起来像这样:

int  * int  -> int (which overflows here during the multiplication)
long * long -> long
long * int  = long * long (by promotion) -> long
int  * long = long (by promotion) * long -> long

此促销几乎普遍适用于数学运算符:使用最宽/最大类型,提升较小的类型并应用x op x -> x表达式(经典,整数与浮动除法)。

L产生一个长值,因此所选的乘法是long * long (by promotion) -> long,它没有发现的立即溢出。 long表达式结果类型传播到所有其他乘法。

奖励积分:如果写成1000 * 60 * 60 * 24 * 30 * 1L为什么会失败(溢出)?

答案 3 :(得分:2)

大于Integer.MAX_VALUE 2147483647

默认情况下,所有数字文字都被视为Integer。要定义Long数字值,您必须使用该数字添加L或'l'。

答案 4 :(得分:1)

该行为的原因是integer overflow

您的第一个陈述可以理解为:

long time = 1000 * 60 * 60 * 24 * 30;

相同
int time = 1000 * 60 * 60 * 24 * 30;
long timel = time;

首先计算表达式,然后分配给long类型;


将后缀L添加到文字时,将其定义为long类型。

JSL 3.10.1. Integer Literals

  

如果整数文字以ASCII为后缀,则其长度为long   字母L或l(ell);否则它的类型为int(§4.2.1)。

long time = 1000L * ( 60 * 60 * 24 * 30);

也可以写成

long time = ((long) 1000) * ( 60 * 60 * 24 * 30);

有关Primitive Data Types

的更多信息

答案 5 :(得分:0)

It is causing for Integer overflow(Max value upto 2147483647). 

您可以在任意数值的末尾加上 L

1000L

然后强制转换为Long类型

答案 6 :(得分:0)

这里发生的是右手侧在分配到左侧之前进行评估。由于您将多个int相乘,因此结果类型将为int。然后,在评估右侧之后,它将看到它应该将此值分配给long,并自动执行转换。

所以你有:

评估右侧为int:1000 * 60 * 60 * 24 * 30 = 2,592,000,000

int的最大值为:2,147,483,647

所以你有一个溢出,这使得int为负。然后将其分配给一个很长的,仍然是否定的。

当您将右侧的一个操作数指定为long时,将评估表达式的long,其最大值会大得多。

答案 7 :(得分:0)

公式中的每个数字都是一个整数,因此Java将在Integer中执行所有计算,并将结果临时存储为Integer。但是结果超过了整数最大范围(溢出),因此它变为负数。

1000 * 60 * 60 * 24 * 30 = 2592000000(超过Integer.MAX_VALUE)

只有当Java需要将其分配给Long变量时,Java才会将其转换为Long。由于结果已经是错误的结果(由于溢出),因此将为Long变量分配错误的结果。

但是,如果您已将1000声明为Long(1000L),那么剩余的计算将以Long而不是Integer的形式完成。