Fixing the “java: integer number too large” Error – 修复“java:整数太大”错误

最后修改: 2022年 10月 27日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Java stores Integer using 32 bits of memory. Thus, Integer‘s(or int‘s) range is from -231 (-2,147,483,648) to 231-1 (2,147,483,647)Therefore, when we see an error message like “java: integer number too large …“, we can usually easily find the problem and fix it.

Java使用32位的内存来存储Integer。因此,Integer的(或int的)范围是从-231(-2,147,483,648)231-1(2,147,483,647)因此,当我们看到类似”java: integer number too large …“的错误信息时,我们通常可以很容易地找到问题所在并加以解决。

However, in some cases, when we see this error message, we might not understand why the error occurred. And it’ll take some time to fix the problem.

然而,在某些情况下,当我们看到这个错误信息时,我们可能不明白为什么会发生这个错误。而且需要花一些时间来解决这个问题。

So, in this tutorial, we’ll take a closer look at a couple of pitfalls that lead to this error and address the reason behind the error.

因此,在本教程中,我们将仔细研究导致这一错误的几个陷阱,并解决该错误背后的原因。

2. Integer Literals Pitfall #1

2.整数字头的陷阱#1

The Java compiler complains when we assign a literal number out of the mentioned integer range to an int variable. For example, let’s say we compile this assignment:

当我们给一个int变量分配一个超出所述整数范围的字面数字时,Java编译器会抱怨。例如,假设我们编译了这个赋值。

int a = 12345678912345;

The compiler reports this error:

编译器报告了这个错误。

java: integer number too large

We can quickly find the problem by reading the error message. We may think int is not the right type for such a big number, so we change the type to long:

我们可以通过阅读错误信息快速找到问题所在。我们可能认为int不是这么大的数字的正确类型,所以我们把类型改为long

long a = 12345678912345;

However, when we recompile the code, we get the same compilation error: “integer number too large“. We’ll wonder why the compiler still complains about integer, although we declared the variable as long? Next, we may spend some time double-checking if we saved the file correctly or restarting the IDE, and so on. However, the problem still stays.

然而,当我们重新编译代码时,我们得到同样的编译错误。”整数太大“。我们会想,虽然我们把变量声明为long,但为什么编译器还是抱怨整数呢?接下来,我们可能会花一些时间仔细检查我们是否正确保存了文件,或者重新启动IDE,等等。然而,问题仍然存在。

When we write number literals in Java, no matter whether it’s within or outside the integer range, Java treats it as the Integer/int type. If we want an integer literal to be long, we must add the ‘L‘ or ‘l‘ suffix. This is also explicitly stated in the Java Language Specification:

当我们在Java中写数字字面时,无论它是在整数范围内还是在整数范围外,Java都将其视为Integer/int类型。如果我们想让一个整数字头成为long,我们必须添加’L‘或’l‘后缀。这在Java语言规范中也有明确规定。

An integer literal is of type long if it is suffixed with an ASCII letter L or l (ell); otherwise it is of type int

如果一个整数字以ASCII字母Ll(ell)为后缀,则其类型为long;否则其类型为int

Therefore, to fix the problem, we should add an ‘L‘ after the literal number:

因此,为了解决这个问题,我们应该在字面数字后面加一个’L‘。

long a = 12345678912345L;

It’s worth mentioning when we use decimal literals without any suffix, Java treats them as double. In case we want them to be float, we must add an ‘F‘ or ‘f‘ suffix:

值得一提的是当我们使用没有任何后缀的小数字时,Java会将其视为double。如果我们想让它们成为float,我们必须添加一个’F‘或’f‘后缀:

float a = 1024.42; // compiler error -  java: incompatible types: possible lossy conversion from double to float
float a = 1024.42F; // compiled

3. Integer Literals Pitfall #2

3.整数字头的陷阱#2

Now we understand that we should add the ‘L‘ suffix to integer literals for the long type. Next, let’s see another example:

现在我们明白了,我们应该为long类型的整数字加上’L‘后缀。接下来,让我们看看另一个例子。

long a = 007L;

As the code above shows, we have the suffix ‘L‘ this time, and a‘s type is long. The code compiles smoothly even if there are leading zeros. If we check a’s value, the variable a holds 7, as expected. So, we may think Java is so intelligent that it ignores the leading zeros of numbers.

如上面的代码所示,我们这次有了后缀’L‘,a的类型是long。即使有前导零,代码也能顺利编译。如果我们检查a’的值,变量a持有7,正如预期的那样。所以,我们可能会认为Java很聪明,它忽略了数字的前导零。

Now, let’s declare another variable:

现在,让我们声明另一个变量。

long b = 008L;

Again, the compiler reports “integer number too large” if we compile the code.

同样,如果我们编译这段代码,编译器会报告”整数太大“。

This time, there’s no sign of an integer in our code. Furthermore, long a = 007L; has worked without any problem. Why does long b = 008L fail? It may take some time to solve the problem.

这一次,我们的代码中没有出现整数的迹象。此外,long a = 007L;一直在工作,没有任何问题。为什么long b = 008L会失败?这可能需要一些时间来解决这个问题。

Actually, we’ve fallen into another integer literals pitfall. This is because, in Java, an integer literal can also be expressed in octal (base 8). Further, an octal integer consists of a leading zero followed by one or more of the digits 0 through 7.

实际上,我们已经陷入了另一个整数字面的陷阱。这是因为,在Java中,一个整数字头也可以用八进制(base 8)表示。此外,一个八进制整数由一个前导零和一个或多个数字0到7组成

Therefore, everything’s fine when we assign ‘007L‘ to a variable. This is because Java reads the octal integer literal ‘007′, and treats it as long. However, when we assign ‘008L‘ to a variable, 008 is not a valid octal integer. Thus, the compiler reports that error.

因此,当我们将’007L‘分配给一个变量时,一切都很好。这是因为Java读取了八进制整数字’007′,并将其视为long。然而,当我们将’008L‘赋值给一个变量时,008不是一个有效的八进制整数。因此,编译器会报告这个错误。

After we understand the cause of the problem, the fix is pretty simple – removing the leading zeros:

在我们了解了问题的原因后,修复方法非常简单–去除前导零。

long b = 8L;

4. Conclusion

4.总结

In this article, we’ve discussed two common pitfalls when we work with integer literals in Java.

在这篇文章中,我们讨论了在Java中使用整数字元时的两个常见陷阱。

Understanding the reason behind the compilation error may help us find and fix the problem quickly.

了解编译错误背后的原因可能有助于我们迅速找到并解决这个问题。