I was making some tests with numeric conversions and casts in Java and I found this strange behaviour (开发者_开发百科for me)
class Test {
public static void main(String[] args) {
//int y = 100000000000000; //does not compile
int x = 100000 * 1000000000; //compile (why?)
System.out.println(x); //x is 276447232
}
}
Basically x and y should be the same number: why does it compile?
Integer overflow goes undetected in Java, that's why the multiplication works fine. However, the literal you were stating was too large and thus is a compiler error.
I guess while the vast majority of Java compilers will precompute that value at compilation time that is not required by the JLS. Thus it cannot be an error, since then different compilers may compile a piece of code or yield errors – something that isn't so nice.
The Sun Java compiler actually performs the calculation as the disassembly shows:
Compiled from "x.java"
class x extends java.lang.Object{
x();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2; //int 276447232
2: istore_1
3: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
6: iload_1
7: invokevirtual #4; //Method java/io/PrintStream.println:(I)V
10: return
The important thing to note here is that for all intents and purposes the result must be the same as if it were computed during runtime. Therefore no compiler error can occur here.
Java deals with overflowing an integer not by an exception but by instead flipping over to negative values and continuing upward.
As an example, here's this code snippet:
int x = Integer.MAX_VALUE + 1;
System.out.println(x);
Java deals with it the best it can. That snippet outputs:
-2147483648
Which is the value of Integer.MIN_VALUE. You just have to be careful when you are dealing with really big numbers. That's why Java has a BigInteger
class to deal with arbitrarily big numbers that go beyond the limit of integers.
精彩评论