¿Por qué Integer.MAX_VALUE + 1 == Integer.MIN_VALUE?

System.out.println(Integer.MAX_VALUE + 1 == Integer.MIN_VALUE);

es verdad.

Entiendo que el entero en Java es de 32 bits y no puede ir por encima de 2 ^ 31-1, pero no puedo entender por qué agregar 1 a su MAX_VALUE da como resultado MIN_VALUE y no en algún tipo de excepción. Sin mencionar algo así como la conversión transparente a un tipo más grande, como lo hace Ruby.

¿Este comportamiento está especificado en alguna parte? ¿Puedo confiar en eso?

Porque el entero se desborda. Cuando se desborda, el siguiente valor es Integer.MIN_VALUE . Relevante JLS

Si una sum entera se desborda, entonces el resultado son los bits de orden bajo de la sum matemática representados en algún formato de complemento de dos suficientemente grande. Si se produce un desbordamiento, entonces el signo del resultado no es el mismo que el signo de la sum matemática de los dos valores de operando.

El almacenamiento entero se desborda y eso no está indicado de ninguna manera, como se indica en JSL 3rd Ed. :

Los operadores enteros incorporados no indican desbordamiento o subdesbordamiento de ninguna manera. Los operadores enteros pueden lanzar una NullPointerException si se requiere la conversión de unboxing (§5.1.8) de una referencia nula. Aparte de eso, los únicos operadores enteros que pueden lanzar una excepción (§11) son el operador de división de enteros / (§15.17.2) y el operador de rest entero % (§15.17.3) , que arrojan una ArithmeticException si el derecho- el operando de mano es cero, y los operadores de incremento y decremento ++ ( §15.15.1 , §15.15.2 ) y -- ( §15.14.3 , §15.14.2 ), que pueden arrojar un OutOfMemoryError si la conversión del boxeo (§5.1) .7) es necesario y no hay suficiente memoria disponible para realizar la conversión.

Ejemplo en un almacenamiento de 4 bits:

 MAX_INT: 0111 (7) MIN_INT: 1000 (-8) 

MAX_INT + 1:

  0111+ 0001 ---- 1000 

Creo que este enlace explica lo que estás viendo: http://en.wikipedia.org/wiki/Two's_complement

Debe comprender cómo se representan los valores enteros en forma binaria y cómo funciona la adición binaria. Java usa una representación llamada complemento de dos, en la cual el primer bit del número representa su signo. Siempre que agregue 1 al entero más grande de Java, que tiene un signo de bit de 0, su signo de bit se convierte en 1 y el número se vuelve negativo.

Este enlace explica con más detalles: http://www.cs.grinnell.edu/~rebelsky/Espresso/Readings/binary.html#integers-in-java

La Especificación del lenguaje Java trata este comportamiento aquí: http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.18.2

Si una sum entera se desborda, entonces el resultado son los bits de orden bajo de la sum matemática representados en algún formato de complemento de dos suficientemente grande. Si se produce un desbordamiento, entonces el signo del resultado no es el mismo que el signo de la sum matemática de los dos valores de operando.

Lo que significa que puede confiar en este comportamiento.

La misma razón por la cual la fecha cambia cuando cruzas la línea de fecha internacional: hay una discontinuidad allí. Está integrado en la naturaleza de la adición binaria.

Este es un problema bien conocido relacionado con el hecho de que los enteros se representan como un complemento de dos hacia abajo en la capa binaria. Cuando agrega 1 al valor máximo del número de complemento de dos, obtiene el valor mínimo. Honestamente, todos los enteros se comportaron de esta manera antes de que existiera Java, y cambiar este comportamiento para el lenguaje Java habría agregado más sobrecarga a las matemáticas enteras, y a progtwigdores confundidos provenientes de otros idiomas.

En la mayoría de los procesadores, las instrucciones aritméticas no tienen modo de falla en un desbordamiento. Establecen una bandera que debe ser revisada. Esa es una instrucción adicional, probablemente más lenta. Para que las implementaciones de idioma sean lo más rápidas posible, los idiomas se especifican con frecuencia para ignorar el error y continuar. Para Java, el comportamiento se especifica en el JLS . Para C, el lenguaje no especifica el comportamiento, pero los procesadores modernos se comportarán como Java.

Creo que hay propuestas de bibliotecas (incómodas) de Java SE 8 para arrojar en desbordamiento, así como las operaciones sin firmar. Un comportamiento, creo que es popular en el mundo de DSP, es fijar los valores en los máximos, por lo que Integer.MAX_VALUE + 1 == Integer.MAX_VALUE [no Java].

Estoy seguro de que los idiomas futuros usarán entradas de precisión arbitrarias, pero no por un tiempo todavía. Requiere un diseño de comstackdor más caro para ejecutarse rápidamente.

Cuando agrega 3 (en el binario 11 ) a 1 (en el binario 1 ), debe cambiar a 0 (en el binario 0 ) todos los binarios 1 comenzando desde la derecha, hasta que obtenga 0, que debe cambiar a 1 . Integer.MAX_VALUE tiene todos los lugares llenos con 1 por lo que solo quedan 0 s.