1. Comparações
Os programadores precisam comparar diferentes variáveis umas com as outras o tempo todo. Mas, como você já viu, nem tudo é tão simples.
Os números inteiros são muito fáceis de comparar — basta usar ==
e pronto. Para comparar números reais , você deve comparar sua diferença (ou melhor, o valor absoluto da diferença) com algum número muito pequeno.
Comparar strings é ainda mais difícil. Acima de tudo, isso ocorre porque strings são objetos. Além do mais, os programadores geralmente desejam que a comparação de strings seja um pouco diferente, dependendo da situação.
2. Como as strings são organizadas na memória
Como você já viu, as strings são armazenadas na memória de maneira diferente dos números inteiros e reais:
Dois blocos de memória são usados para armazenar strings: um bloco armazena o próprio texto (seu tamanho depende do tamanho do texto) enquanto o segundo bloco (4 bytes) armazena o endereço do primeiro bloco.
Embora um programador experiente diria algo como "a String
str
variável armazena uma referência a um String
objeto.
3. Atribuindo referências a uma string
Os benefícios dessa abordagem tornam-se aparentes quando você precisa atribuir uma variável de string a outra variável de string. Exemplo:
String text = "This is a very important message";
String message = text;
E aqui está o que a memória conterá como resultado:
Após esse tipo de operação de atribuição, o String
objeto permanece onde estava e apenas seu endereço (uma referência ao objeto) é copiado para a message
variável.
4. Trabalhando com referências e objetos
Mas se você decidir converter uma string para maiúsculas (letras maiúsculas), a máquina Java faz tudo certo: você vai acabar com dois String
objetos, e as variáveis text
e message
vão armazenar referências, cada uma para seu próprio objeto.
Exemplo:
String text = "This is a very important message";
String message = text.toUpperCase();
E aqui está o que a memória conterá como resultado:
Observe que o toUpperCase()
método não altera a string em que é chamado. Em vez disso, ele cria uma nova string (novo objeto) e retorna uma referência a ela.
Que tal um exemplo ainda mais interessante. Digamos que você decida passar uma string para um Scanner
objeto (para que ele leia os valores da string).
Exemplo:
String text = "10 20 40 80";
Scanner console = new Scanner(text);
int a = console.nextInt();
int b = console.nextInt();
Você pode aprender mais sobre como a Scanner
classe funciona aqui .
É assim que tudo ficará armazenado na memória:
Nesse caso, um único String
objeto permanece na memória exatamente como estava — apenas as referências a ele são passadas e armazenadas em variáveis.
5. Comparando referências a String
objetos
E, finalmente, chegamos à parte divertida: comparação de strings.
Existem dois operadores que você pode usar para comparar variáveis de string: ==
(igual) e !=
(diferente). Você não pode usar os operadores "maior que", "menor que" ou "maior que ou igual a" — o compilador não permitirá isso.
Mas há uma nuance interessante aqui: o que realmente é armazenado em variáveis de string? Isso mesmo: endereços (referências) a objetos. E são esses endereços que serão comparados:
String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase();
Aqui está o que ficará na memória:
As variáveis message
e text
referem-se (armazenam o endereço) ao mesmo objeto. Mas as variáveis s1
e s2
armazenam referências a objetos que são muito semelhantes, mas distintos.
E se você comparar essas 4 variáveis no código, obterá o seguinte resultado:
Código | Saída do console |
---|---|
|
|
GO TO FULL VERSION