Jeje, curioso. Creo que esto es un "error intencional", por así decirlo.
La razón subyacente es cómo se escribe la clase Integer. Básicamente, parseInt está "optimizado" para números positivos. Cuando analiza la cadena, genera el resultado de forma acumulativa, pero se niega. Luego cambia el signo del resultado final.
Ejemplo:
66 = 0x42
analizado como:
4*(-1) = -4
-4 * 16 = -64 (hex 4 parsed)
-64 - 2 = -66 (hex 2 parsed)
return -66 * (-1) = 66
Ahora, veamos su ejemplo 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.
Editar (adición): para que parseInt () funcione "consistentemente" para -Integer.MAX_VALUE <= n <= Integer.MAX_VALUE, habrían tenido que implementar la lógica para "rotar" al alcanzar -Integer.MAX_VALUE en el resultado acumulativo, comenzando de nuevo en el extremo máximo del rango de enteros y continuando hacia abajo desde allí. Por qué no hicieron esto, habría que preguntarle a Josh Bloch oa quien sea que lo implementó en primer lugar. Podría ser solo una optimización.
Sin embargo,
Hex=Integer.toHexString(Integer.MAX_VALUE);
System.out.println(Hex);
System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));
funciona bien, solo por esta razón. En el código fuente de Integer puedes encontrar este comentario.