Hehe, ciekawy. Myślę, że to „intencjonalny błąd”, że tak powiem.
Podstawowym powodem jest sposób zapisu klasy Integer. Zasadniczo parseInt jest „zoptymalizowany” dla liczb dodatnich. Kiedy analizuje ciąg, buduje skumulowany wynik, ale zanegowany. Następnie odwraca znak wyniku końcowego.
Przykład:
66 = 0x42
przeanalizowane jak:
4*(-1) = -4
-4 * 16 = -64 (hex 4 parsed)
-64 - 2 = -66 (hex 2 parsed)
return -66 * (-1) = 66
Spójrzmy teraz na Twój przykład FFFF8000
16*(-1) = -16 (first F parsed)
-16*16 = -256
-256 - 16 = -272 (second F parsed)
-272 * 16 = -4352
-4352 - 16 = -4368 (third F parsed)
-4352 * 16 = -69888
-69888 - 16 = -69904 (forth F parsed)
-69904 * 16 = -1118464
-1118464 - 8 = -1118472 (8 parsed)
-1118464 * 16 = -17895552
-17895552 - 0 = -17895552 (first 0 parsed)
Here it blows up since -17895552 < -Integer.MAX_VALUE / 16 (-134217728).
Attempting to execute the next logical step in the chain (-17895552 * 16)
would cause an integer overflow error.
Edycja (dodawanie): aby parseInt () działało „konsekwentnie” dla -Integer.MAX_VALUE <= n <= Integer.MAX_VALUE, musieliby zaimplementować logikę „rotacji” po osiągnięciu -Integer.MAX_VALUE w skumulowany wynik, zaczynając od maksymalnego końca zakresu liczb całkowitych i kontynuując w dół od tego miejsca. Dlaczego tego nie zrobili, należałoby zapytać Josha Blocha lub tego, kto to wdrożył. To może być tylko optymalizacja.
Jednak,
Hex=Integer.toHexString(Integer.MAX_VALUE);
System.out.println(Hex);
System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));
działa dobrze, tylko z tego powodu. W źródle Integer można znaleźć ten komentarz.