解决“java: 整数数字太大”错误
解决“java: 整数数字太大”错误
Java使用32位内存来存储_Integer_。因此,Integer(或_int_)的范围是从-231(-2,147,483,648)到231-1(2,147,483,647)。因此,当我们看到像“java: integer number too large …”这样的错误消息时,我们通常可以很容易地找到问题并修复它。
然而,在某些情况下,当我们看到这个错误消息时,我们可能不明白为什么会出现这个错误。而且,解决这个问题可能需要一些时间。
所以,在本教程中,我们将更仔细地看看导致这个错误的几个陷阱,并解决错误背后的原因。
2. 整数字面量陷阱 #1
当Java编译器在我们为_int_变量分配一个超出上述整数范围的字面量数字时会发出抱怨。例如,假设我们编译这个赋值:
int a = 12345678912345;
编译器报告这个错误:
java: integer number too large
我们可以通过阅读错误消息快速找到问题。我们可能认为_int_不是这样一个大数字的正确类型,所以我们将类型更改为_long_:
long a = 12345678912345;
然而,当我们重新编译代码时,我们得到相同的编译错误:“integer number too large”。我们会想知道为什么编译器仍然抱怨整数,尽管我们声明了变量为_long_?接下来,我们可能会花一些时间检查我们是否正确保存了文件或重新启动了IDE等等。然而,问题仍然存在。
当我们在Java中写入数字字面量时,无论它是否在整数范围内,Java都将其视为_Integer/int_类型。如果**我们想要一个整数字面量是_long_,我们必须在字面量数字后添加‘L‘或‘l‘后缀。**这也是在Java语言规范中明确说明的:
一个整数字面量如果带有ASCII字母_L_或_l_(ell)的后缀,则是_long_类型;否则它是_int_类型。
因此,为了解决这个问题,我们应该在字面量数字后加上一个‘L‘:
long a = 12345678912345L;
值得一提的是当我们使用没有后缀的小数字面量时,Java将它们视为_double_。如果我们想要它们是_float_,我们必须添加一个‘F‘或‘f‘后缀:
float a = 1024.42; // 编译器错误 - java: incompatible types: possible lossy conversion from double to float
float a = 1024.42F; // 编译通过
3. 整数字面量陷阱 #2
现在我们知道应该为_long_类型添加‘L‘后缀。接下来,让我们看另一个例子:
long a = 007L;
正如上面的代码所示,这次我们有了后缀‘L‘,并且_a_的类型是_long_。即使有前导零,代码也能顺利编译。如果我们检查_a_的值,变量_a_持有7,正如预期的那样。所以,我们可能认为Java非常聪明,它忽略了数字的前导零。
现在,让我们声明另一个变量:
long b = 008L;
再次,如果我们编译代码,编译器报告“integer number too large”。这次,我们的代码中没有整数的迹象。此外,_long a = 007L;_没有问题地工作。为什么_long b = 008L_失败了?解决这个问题可能需要一些时间。
实际上,我们陷入了另一个整数字面量的陷阱。这是因为,在Java中,一个整数字面量也可以以八进制(基数8)表示。进一步,一个八进制整数由一个前导零后面跟着一个或多个0到7的数字组成。
因此,当我们将‘007L‘赋值给一个变量时,一切都很好。这是因为Java读取八进制整数字面量‘007’,并将其视为_long_。然而,当我们将‘008L‘赋值给一个变量时,008不是一个有效的八进制整数。因此,编译器报告了那个错误。
在我们理解了问题的原因之后,修复方法非常简单——去掉前导零:
long b = 8L;
4. 结论
在本文中,我们讨论了在Java中使用整数字面量时遇到的两个常见陷阱。
理解编译错误的原因是帮助我们快速找到并解决问题的关键。