str
não é um objeto, é uma referência a um objeto. "Hello"
e "Help!"
são dois String
objetos distintos . Assim, str
aponta para uma string. Você pode mudar para o que aponta , mas não para o que aponta .
Veja este código, por exemplo:
String s1 = "Hello";
String s2 = s1;
// s1 and s2 now point at the same string - "Hello"
Agora, não há nada 1 que poderíamos fazer para s1
que afetaria o valor de s2
. Eles se referem ao mesmo objeto - a string "Hello"
- mas esse objeto é imutável e, portanto, não pode ser alterado.
Se fizermos algo assim:
s1 = "Help!";
System.out.println(s2); // still prints "Hello"
Aqui vemos a diferença entre alterar um objeto e alterar uma referência. s2
ainda aponta para o mesmo objeto que definimos inicialmente s1
. Definir s1
como "Help!"
apenas altera a referência , enquanto o String
objeto a que se referiu originalmente permanece inalterado.
Se as strings fossem mutáveis, poderíamos fazer algo assim:
String s1 = "Hello";
String s2 = s1;
s1.setCharAt(1, 'a'); // Fictional method that sets character at a given pos in string
System.out.println(s2); // Prints "Hallo"
Editar para responder à edição do OP:
Se você olhar o código fonte para String.replace (char, char) (também disponível em src.zip no diretório de instalação do JDK - uma dica profissional é procurar sempre que você se perguntar como algo realmente funciona), poderá ver o que faz é o seguinte:
- Se houver uma ou mais ocorrências de
oldChar
na sequência atual, faça uma cópia da sequência atual em que todas as ocorrências de oldChar
são substituídas newChar
.
- Se
oldChar
não estiver presente na cadeia atual, retorne a cadeia atual.
Então, sim, "Mississippi".replace('i', '!')
cria um novo String
objeto. Novamente, o seguinte vale:
String s1 = "Mississippi";
String s2 = s1;
s1 = s1.replace('i', '!');
System.out.println(s1); // Prints "M!ss!ss!pp!"
System.out.println(s2); // Prints "Mississippi"
System.out.println(s1 == s2); // Prints "false" as s1 and s2 are two different objects
Por enquanto, sua tarefa de casa é ver o que o código acima faz se você mudar s1 = s1.replace('i', '!');
para s1 = s1.replace('Q', '!');
:)
1 Na verdade, é possível alterar as strings (e outros objetos imutáveis). Requer reflexão e é muito, muito perigoso e nunca deve ser usado, a menos que você esteja realmente interessado em destruir o programa.