Entendendo a igualdade
No Capítulo 2, você aprendeu como usar == para comparar números e referências a objetos do mesmo objeto.
StringBuilder one = new StringBuilder();
StringBuilder two = new StringBuilder();
StringBuilder three = one.append("a");
System.out.println(one == two); // false
System.out.println(one == three); // true
Como este exemplo não está lidando com primitivos, nós sabemos procurar referências estão se referindo ao mesmo objeto. one e two são completamente separados StringBuilders, nos dando dois objetos. Portanto, a primeira declaração de impressão nos dá falso. three é mais interessante. Lembre-se de como os métodos StringBuilder gostam de retornar referência corrente para encadeamento? Isso significa que one e three apontam para o mesmo objeto e a segunda declaração de impressão nos mostra a verdade.
Vamos agora visitar o cenário mais complexo e confuso, igualdade de String, feito em parte por causa da maneira como a JVM reutiliza literais de String :
String x = "Hello World";
String y = "Hello World";
System.out.println(x == y); // true
Lembre-se de que String s são imutáveis e literais são agrupados. A JVM criou apenas um literal na memória. x e y apontam para o mesmo local na memória; Portanto, a declaração é verdadeira. Fica ainda mais complicado. Considere este código:
String x = "Hello World";
String z = " Hello World".trim();
System.out.println(x == z); // false
Neste exemplo, não temos dois do mesma literal de String . Embora x e z acontece para avaliar a mesma seqüência, uma é calculada em tempo de execução. Já que não é o mesmo em tempo de compilação, um novo objeto String é criado.
Você pode até forçar o problema criando uma nova String :
String x = new String("Hello World");
String y = "Hello World";
System.out.println(x == y); // false
Como você solicitou especificamente um objeto String diferente, o valor do pool não é compartilhado.
A lição é nunca usar == para comparar objetos String . A única vez você deve ter que lidar com == para String s está no exame.
Você viu anteriormente que pode dizer que queremos igualdade lógica em vez de igualdade de objeto para objetos String :
String x = "Hello World";
String z = " Hello World".trim(); System.out.println(x.equals(z)); // true
Isso funciona porque os autores da classe String implementaram um método padrão chamado equals para verificar os valores dentro da String em vez da própria String . Se um classe não tem um método equals, Java determina se as referências apontam para o mesmo objeto - que é exatamente o que == faz. Caso você deve estar se perguntando, os autores de StringBuilder não implementou equals(). Se você chamar equals () em duas instâncias StringBuilder, verificará a igualdade de referência.
O exame irá testá-lo em sua compreensão da igualdade com objetos que eles definem também.
Por exemplo:
1: public class Tiger {
2: String name;
3: public static void main(String[] args) {
4: Tiger t1 = new Tiger();
5: Tiger t2 = new Tiger();
6: Tiger t3 = t1;
7: System.out.println(t1 == t1); // true
8: System.out.println(t1 == t2); // false
9: System.out.println(t1.equals(t2)); // false
10: } }
As duas primeiras instruções verificam a igualdade de referência do objeto. Linha 7 imprime true porque nós estamos comparando referências do mesmo objeto. A linha 8 imprime false porque as duas referências do objetos são diferentes. A linha 9 imprime false, pois o Tiger não implementa equals().
Não se preocupe - não se espera que você saiba como implementar equals() para o exame da OCA.