Vou tentar explicar da melhor maneiro possível, simples, direta e com muitas referencias, qualquer coisa errada não deixem de corrigir.
// Exemplo 1:
Integer i = 0;
Integer i2 = 0; Quando ele cria esses dois valores na memória desta forma “simples”, em uma variável de referencia, eles assumem o mesmo valor binário na memória (Exemplo ID=19) valendo é lógico para os dois zeros, ou seja, os zeros são IDS=19, esses dois valores i e i2 iram referencia o mesmo ID, entendeu? De novo, essas duas referencias criadas “i e i2” tem a mesma referencia porque os 2 são do mesmo valor (0) e por isso tem o mesmo numero interno (ID) logicamente com a mesma referencia. Voltando ao assunto de b[/b], ele compara se essas referencias apontam para o mesmo objeto na memoria b[/b], tendo a mesma referencia retorna “true”. b[/b] compara os objetos dentro do heap ou seja, comparando os zeros(0), já que os dois valores são zeros(0) ele retorna “true”
// observação:
Integer i = 0;
Integer i2 = 7; Ele cria 2 valores no sistema, e faz essas duas referenciarem esses valores distintos, da para ver que agora os valores são diferentes certo? então, ele cria o (i com um ID=19) e (i2 com ID=24), logicamente comparando com b[/b] vai retorna “false” e com “equals” também vai retorna “false” porque os valores são diferentes.
// Exemplo 2:
Integer i3 = new Integer(0);
Integer i4 = new Integer(0); Ja que usamos a palavra “new” ele criará um novo objeto na memoria interna com um numero de ID diferente para os 2 objetos criados com “new”, (Exemplo: com i3 com ID=19 e i4 com ID=24) mesmo que os números fossem iguais ele iria comparar a ID criada do objeto por isso que a comparação de “==”, que compara as referencias vai retorna “false” e equals comparando dentro do heap vai retorna “true” já que ambos são zeros.