Tava voltando pra casa e acabei pensando nessa situação que vc postou.
Integer a = new Integer(25);
Integer b = a;
Integer c = a;
c = c.intValue();
System.out.println(c == a);// retorna false
O que acontece é que quando vc cria: Integer a = new Integer(25); vc está criando um objeto.
Quando faz: Integer c = a; o que acontece é que c recebe uma cópia do objeto criado. Por isso se vc fizer o teste: System.out.println(c == a); logo em seguida o retorno será true.
Mas quando faz: c = c.intValue(); vc está fazendo um Unboxing que na verdade é quando você quer converter o valor de um objeto para seu correspondente tipo primitivo.
O boxing é o contrário, quando vc quer corresponder o tipo primitivo para um objeto.
no caso C é no momento um objeto, já que ele é uma cópia de A. Quando vc faz: c = c.intValue(); vc então passa a transformar seu objeto em um tipo primitivo.
Então seria mais ou menos assim em outras palavras:
O processo de Encapsular um Tipo Primitivo em um Objeto chamamos de Boxing.
O processo de Desencapsular um Objeto em um Tipo Primitivo chamamos de UnBoxing.
A partir do Java 5 esse mecanismo passou a ser automatico e chamado então de AutoBoxing, coisa que era feita manualmente pelos programadores até o java 1.4.