porque Integer.MAX_VALUE + 1 == Integer.MIN_VALUE?

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

é verdade.

Eu entendo que o inteiro em Java é de 32 bits e não pode ir acima de 2 ^ 31-1, mas não consigo entender por que adicionar 1 aos seus MAX_VALUE resulta em MIN_VALUE e não em algum tipo de exceção. Não mencionando algo como conversão transparente para um tipo maior, como o Ruby faz.

Esse comportamento é especificado em algum lugar? Posso confiar nisto?

Porque o inteiro transborda. Quando transborda, o próximo valor é Integer.MIN_VALUE . JLS relevante

Se uma adição inteira estourar, o resultado são os bits de baixa ordem da sum matemática, conforme representados em alguns formatos de complemento de dois suficientemente grandes. Se ocorrer um estouro, o sinal do resultado não é o mesmo que o sinal da sum matemática dos dois valores do operando.

O armazenamento inteiro fica sobrecarregado e isso não é indicado de forma alguma, como indicado na JSL 3rd Ed. :

Os operadores inteiros integrados não indicam excesso ou estouro de nenhuma maneira. Operadores inteiros podem lançar um NullPointerException se a conversão de unboxing (§5.1.8) de uma referência nula for necessária. Fora isso, os únicos operadores inteiros que podem lançar uma exceção (§11) são o operador de divisão inteira / (§15.17.2) e o operador inteiro de resto % (§15.17.3) , que lança uma ArithmeticException se a direita o operando de mão é zero, e os operadores de incremento e decremento ++ ( §15.15.1 , §15.15.2 ) e -- ( §15.14.3 , §15.14.2 ), que podem lançar um erro OutOfMemoryError se for de boxe (§5.1 .7) é necessário e não há memory suficiente disponível para realizar a conversão.

Exemplo em um armazenamento de 4 bits:

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

MAX_INT + 1:

  0111+ 0001 ---- 1000 

Acredito que este link explica o que você está vendo: http://en.wikipedia.org/wiki/Two's_complement

Você deve entender como valores inteiros são representados em forma binária e como funciona a adição binária. Java usa uma representação chamada complemento de dois, na qual o primeiro bit do número representa seu sinal. Sempre que você adicionar 1 ao maior número inteiro de java, que tem um sinal de bit 0, seu sinal de bit se torna 1 e o número fica negativo.

Esses links são explicados com mais detalhes: http://www.cs.grinnell.edu/~rebelsky/Espresso/Readings/binary.html#integers-in-java

A especificação da linguagem Java trata desse comportamento aqui: http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.18.2

Se uma adição inteira estourar, o resultado são os bits de baixa ordem da sum matemática, conforme representados em alguns formatos de complemento de dois suficientemente grandes. Se ocorrer um estouro, o sinal do resultado não é o mesmo que o sinal da sum matemática dos dois valores do operando.

O que significa que você pode confiar nesse comportamento.

A mesma razão pela qual a data muda quando você cruza a linha de data internacional: há uma descontinuidade lá. Está embutido na natureza da adição binária.

Esta é uma questão bem conhecida relacionada ao fato de que Integers são representados como dois complementos na camada binária. Quando você adiciona 1 ao valor máximo do número de complemento de dois, você obtém o valor mínimo. Honestamente, todos os inteiros se comportavam dessa maneira antes da existência do java, e a mudança desse comportamento para a linguagem Java teria adicionado mais sobrecarga à matemática inteira e programadores confusos vindos de outras linguagens.

Na maioria dos processadores, as instruções aritméticas não têm modo de falha em um estouro. Eles definem uma bandeira que deve ser verificada. Essa é uma instrução extra, provavelmente mais lenta. Para que as implementações de linguagem sejam o mais rápidas possível, os idiomas são freqüentemente especificados para ignorar o erro e continuar. Para Java, o comportamento é especificado no JLS . Para C, a linguagem não especifica o comportamento, mas os processadores modernos se comportarão como Java.

Acredito que há propostas para bibliotecas (desajeitadas) do Java SE 8 lançarem em overflow, bem como em operações não assinadas. Um comportamento, acredito popular no mundo DSP, é clamp os valores no máximo, então Integer.MAX_VALUE + 1 == Integer.MAX_VALUE [não Java].

Tenho certeza de que futuros idiomas usarão ints de precisão arbitrária, mas não por enquanto. Requer design de compilador mais caro para ser executado rapidamente.

Quando você adiciona 3 (no binário 11 ) a 1 (no binário 1 ), você deve alterar para 0 (no binário 0 ) todo o binário 1 a partir da direita, até obter 0, que deve ser alterado para 1 . Integer.MAX_VALUE tem todos os lugares preenchidos com 1 , permanecendo apenas 0 s.