Java 为什么长COOKIE_TIMEOUT=1000*60*60*24*30返回负数?

Java 为什么长COOKIE_TIMEOUT=1000*60*60*24*30返回负数?,java,long-integer,Java,Long Integer,输出:-1702967296 有人告诉我把L放在1000后面&这很管用 final long COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30; 产量:259.2亿 为什么会发生这种情况?整数溢出,放入1000L,这将强制长转换 更新 稍长的解释: 例如,如果只做1000*10,java会将它们视为整数。 在原始代码中,您正在进行一个溢出的整数计算,然后将溢出的值转换为long 但是,如果将L放在第一个数字之后,java会将它们视为long(最左边的操作数定义

输出:-1702967296

有人告诉我把L放在1000后面&这很管用

final long COOKIE_TIMEOUT = 1000 * 60 * 60 * 24 * 30;
产量:259.2亿


为什么会发生这种情况?

整数溢出,放入1000L,这将强制长转换

更新 稍长的解释:

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

但是,如果将L放在第一个数字之后,java会将它们视为long(最左边的操作数定义粒度),并且不会出现溢出

另一个例子是以下代码:

final long COOKIE_TIMEOUT = 1000L * 60 * 60 * 24 * 30;
这将打印出:

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

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

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

它比
整数大。最大值
2147483647

默认情况下,所有数字字符都被视为
整数
。要定义
Long
数值,必须将
L
或“L”与数字相加

2.0 != 2.5
您可以在任意数值的末尾加后缀L

1000L


然后它强制转换为长类型

这种行为的原因是

你的第一句话可以这样理解:

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

It is causing for Integer overflow(Max value upto 2147483647). 
首先计算表达式,然后分配给long类型


当您将后缀
L
添加到文字时,您将其定义为长类型

如果整型文字的后缀为ASCII,则其类型为long 字母L或L(ell);否则为int型(§4.2.1)

长时间=1000L*(60*60*24*30)

也可以写成

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


关于

的更多信息尽管
COOKIE\u TIMEOUT
很长
但右侧表达式由整数组成,因此其类型为
int
。结果大于导致溢出的
Integer.MAX\u值。当表达式中至少有一个操作数属于更高类型(例如
long
)时,整个表达式将变为
long
,并且不会发生溢出


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

此处发生的情况是,在分配给左手侧之前,对右手侧进行求值。由于您要将几个
int
s相乘,因此生成的类型将是
int
。然后,在评估右侧后,它将看到应该将此值指定给long,并自动进行铸造

所以你有:

右侧评估为
int
:1000*60*60*24*30=
2592000000

int
的最大值为:
2147483647

所以有一个溢出,它使int为负。然后将其分配给一个长的、仍然为负的


当您将右侧的一个操作数指定为
long
时,将计算表达式的
long
,该表达式的最大值要大得多。

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

int*int->int(在乘法过程中溢出)
长*长->长
long*int=long*long(通过提升)->long
int*long=long(通过提升)*long->long
对于数学运算符,这种提升非常普遍:使用最宽/最大的类型,提升较小的类型,并应用
x op x->x
表达式(经典的整数与浮点除法)

L
产生一个长值,因此选择的乘法是
long*long(通过提升)->long
,不会立即发现溢出。
long
表达式结果类型传播到所有其他乘法


加分:如果写为
1000*60*60*24*30*1L
,它仍然会失败(溢出),为什么?

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

1000*60*60*24*30=2592000000(超过整数最大值)

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


但是,如果您已经将1000声明为Long(1000L),那么剩余的计算将按Long而不是Integer进行。

可能是整数溢出…?我在eClipse中进行了测试,它打印出了负值?+1,
Integer。MAX_值
是2147483647。我在阅读
Long.MAX_值后感到害怕。
前面:p;)嘿嘿。。。这甚至让我吃惊,更正。。。谢谢sp00m和KisHan
int time = 1000 * 60 * 60 * 24 * 30;
long timel = time;