final long COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30;
输出:-1702967296
有人告诉我在1000以后放L?它的工作原理
final long COOKIE_TIMEOUT = 1000L * 60 * 60 * 24 * 30;
输出:2592000000
为什么会这样?
答案 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_TIMEOUT
是long
,但右手表达式由整数组成,因此其类型为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类型。
如果整数文字以ASCII为后缀,则其长度为long 字母L或l(ell);否则它的类型为int(§4.2.1)。
long time = 1000L * ( 60 * 60 * 24 * 30);
也可以写成
long time = ((long) 1000) * ( 60 * 60 * 24 * 30);
答案 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的形式完成。