Considere o seguinte exemplo.
String str = new String();
str = "Hello";
System.out.println(str); //Prints Hello
str = "Help!";
System.out.println(str); //Prints Help!
Agora, em Java, os objetos String são imutáveis. Então, como é str
possível atribuir ao objeto o valor "Ajuda!". Isso não está contradizendo a imutabilidade de strings em Java? Alguém pode me explicar o conceito exato de imutabilidade?
Editar:
Está bem. Agora estou conseguindo, mas apenas uma pergunta de acompanhamento. E o código a seguir:
String str = "Mississippi";
System.out.println(str); // prints Mississippi
str = str.replace("i", "!");
System.out.println(str); // prints M!ss!ss!pp!
Isso significa que dois objetos são criados novamente ("Mississippi" e "M! Ss! Ss! Pp!") E a referência str
aponta para um objeto diferente após o replace()
método?
java
string
immutability
Hand_handle
fonte
fonte
Respostas:
str
não é um objeto, é uma referência a um objeto."Hello"
e"Help!"
são doisString
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:
Agora, não há nada 1 que poderíamos fazer para
s1
que afetaria o valor des2
. 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:
Aqui vemos a diferença entre alterar um objeto e alterar uma referência.
s2
ainda aponta para o mesmo objeto que definimos inicialmentes1
. Definirs1
como"Help!"
apenas altera a referência , enquanto oString
objeto a que se referiu originalmente permanece inalterado.Se as strings fossem mutáveis, poderíamos fazer algo assim:
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:
oldChar
na sequência atual, faça uma cópia da sequência atual em que todas as ocorrências deoldChar
são substituídasnewChar
.oldChar
não estiver presente na cadeia atual, retorne a cadeia atual.Então, sim,
"Mississippi".replace('i', '!')
cria um novoString
objeto. Novamente, o seguinte vale:Por enquanto, sua tarefa de casa é ver o que o código acima faz se você mudar
s1 = s1.replace('i', '!');
paras1 = 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.
fonte
O objeto que faz
str
referência pode mudar, mas os própriosString
objetos reais não podem.Os
String
objetos que contêm a string"Hello"
e"Help!"
não podem alterar seus valores, portanto, são imutáveis.A imutabilidade dos
String
objetos não significa que as referências que apontam para o objeto não podem mudar.Uma maneira de impedir que a
str
referência seja alterada é declará-la comofinal
:Agora, tentar atribuir outro
String
aSTR
causará um erro de compilação.fonte
str
não é o "objeto", é uma referência ao objeto. Se vocêString str = "Hello";
seguiuString anotherReference = str;
você não tem 2 objetos String, você tem um objeto (o literal "Hello") e 2 referências a ele (str
eanotherReference
).Light_handle Eu recomendo que você leia o Tamanho da xícara - uma história sobre variáveis e Valor por passagem por valor (tamanho da xícara continuação) . Isso ajudará bastante ao ler as postagens acima.
Você leu eles? Sim. Boa.
Isso cria um novo "controle remoto" chamado "
str
" e define isso para o valornew String()
(ou""
).por exemplo, na memória, isso cria:
Isso muda o controle remoto "
str
", mas não modifica a string original""
.por exemplo, na memória, isso cria:
Isso altera o controle remoto "
str
", mas não modifica a seqüência original""
ou o objeto para o qual o controle remoto aponta atualmente.por exemplo, na memória, isso cria:
fonte
Vamos dividi-lo em algumas partes
Esta instrução cria uma string contendo hello e ocupa espaço na memória, ou seja, no Constant String Pool e a atribui ao objeto de referência s1
Esta instrução atribui a mesma string hello à nova referência s2
Ambas as referências estão apontando para a mesma string, portanto, imprima o mesmo valor da seguinte maneira.
Embora String seja imutável , a atribuição pode ser possível, portanto o s1 agora se refere à nova pilha de valores .
Mas e quanto ao objeto s2 que está apontando para olá, ele será como é?
Como a String é imutável, a Java Virtual Machine não nos permitirá modificar a string s1 por seu método. Ele criará todo o novo objeto String no pool da seguinte maneira.
Observe que se String seria mutável, a saída teria sido
Agora você pode se surpreender por que o String possui métodos como o concat () para modificar. O fragmento a seguir limpará sua confusão.
Aqui estamos atribuindo o valor modificado da string de volta à referência s1 .
É por isso que Java decidiu que String é uma classe final. Caso contrário, qualquer pessoa pode modificar e alterar o valor da string. Espero que isso ajude um pouco.
fonte
O objeto de sequência que foi referenciado pela primeira vez
str
não foi alterado, tudo o que você fez foi fazerstr
referência a um novo objeto de sequência.fonte
A String não muda, a referência a ela muda. Você está confundindo imutabilidade com o conceito de
final
campos. Se um campo for declarado comofinal
, uma vez atribuído, não poderá ser reatribuído.fonte
Em relação à parte de substituição da sua pergunta, tente o seguinte:
fonte
Embora o java tente ignorá-lo,
str
nada mais é do que um ponteiro. Isso significa que, quando você escreve pela primeira vezstr = "Hello";
, cria um objeto questr
aponta para. Quando você reatribuistr
por escritostr = "Help!";
, um novo objeto é criado e o"Hello"
objeto antigo é coletado como lixo sempre que o java quiser.fonte
Imutabilidade implica que o valor de um objeto instanciado não pode ser alterado; você nunca pode transformar "Olá" em "Ajuda!".
A variável str é uma referência a um objeto. Quando você atribui um novo valor a str, você não está alterando o valor do objeto a que se refere, mas referenciando um objeto diferente.
fonte
A classe String é imutável e você não pode alterar o valor do objeto imutável. Porém, no caso de String, se você alterar o valor de string, ele criará uma nova string no pool de strings e a referência de string a esse valor, e não ao valor mais antigo. então, dessa maneira, a string é imutável. Vamos dar o seu exemplo,
ele criará uma string "Mississippi" e a adicionará ao pool de String. Agora, str está apontando para o Mississippi.
Mas após a operação acima, uma outra string será criada "M! Ss! Ss! Pp!" e será adicionado ao pool de String. e agora str está apontando para M! ss! ss! pp !, não para o Mississippi.
portanto, dessa maneira, quando você alterar o valor do objeto string, ele criará mais um objeto e o adicionará ao pool de strings.
Vamos ter mais um exemplo
isso acima das três linhas adicionará três objetos de string ao pool de strings.
1) Olá
2) Mundo
3) Olá Mundo
fonte
Usar:
Se você vê aqui, eu uso o
concat
método para alterar a string original, ou seja, "New String" com uma string "Added String", mas ainda assim obtive a saída como anterior, portanto isso prova que você não pode alterar a referência do objeto da classe String, mas se você fizer isso pela classe StringBuilder, ele funcionará. Está listado abaixo.fonte
Como Linus Tolvards disse:
Dê uma olhada neste:
A saída é
Então, lembre-se de duas coisas:
fonte
Para aqueles que querem saber como quebrar a imutabilidade de String em Java ...
Código
Resultado
fonte
String é imutável . O que significa que só podemos mudar a referência .
fonte
Em Java, os objetos geralmente são acessados por referências. No seu trecho de código, str é uma referência que é atribuída primeiro a "Hello" (um objeto criado automaticamente ou obtido a partir de um pool constante ) e, em seguida, você atribui outro objeto "Help!" para a mesma referência. Um ponto a ser observado é que a referência é a mesma e modificada, mas os objetos são diferentes. Mais uma coisa no seu código, você acessou três objetos,
Chamar new String () cria um novo objeto, mesmo que exista no pool de strings; portanto, geralmente não deve ser usado. Para colocar uma string criada a partir de new String () no pool de strings, você pode tentar o
intern()
métodoEu espero que isso ajude.
fonte
A imutabilidade que posso dizer é que você não pode alterar a própria String. Suponha que você tenha a String x, cujo valor é "abc". Agora você não pode alterar a String, ou seja, não pode alterar nenhum caractere / s em "abc".
Se você precisar alterar algum caractere na String, poderá usar uma matriz de caracteres e modificá-la ou usar o StringBuilder.
Resultado:
fonte
Ou você pode tentar:
Isso mostrará como o código de hash muda.
fonte
String é imutável significa que você não pode alterar o objeto em si, mas pode alterar a referência ao objeto. Quando você chamou a = "ty", na verdade você está alterando a referência de a para um novo objeto criado pela literal String "ty". Alterar um objeto significa usar seus métodos para alterar um de seus campos (ou os campos são públicos e não finais, para que possam ser atualizados de fora sem acessá-los por métodos), por exemplo:
Enquanto estiver em uma classe imutável (declarada como final, para impedir a modificação por herança) (seus métodos não podem modificar seus campos e também os campos são sempre particulares e recomenda-se que sejam finais), por exemplo, String, você não pode alterar a String atual, mas você pode retornar uma nova String, ou seja:
fonte
Aqui imutabilidade significa que a instância pode apontar para outra referência, mas o conteúdo original da string não seria modificado na referência original. Deixe-me explicar pelo primeiro exemplo dado por você. O primeiro str está apontando para "Hello", está tudo bem com isso. Segunda vez, está apontando para "Ajuda!". Aqui str começou a apontar para "Ajuda!" e a referência da string "Hello" é perdida e não podemos recuperá-la.
De fato, quando str tentaria modificar o conteúdo existente, outra nova string será gerada e str começará a apontar para essa referência. Portanto, vemos que a string na referência original não é modificada, mas é segura em sua referência e a instância do objeto começou a apontar para uma referência diferente, para que a imutabilidade seja preservada.
fonte
Tarde demais para a resposta, mas queria colocar uma mensagem concisa do autor da classe String em Java
Pode-se derivar desta documentação que qualquer coisa que mude a string retorne um objeto diferente (que pode ser novo ou interno e antigo). A dica não tão sutil sobre isso deve vir da assinatura da função. Pense nisso: 'Por que eles fizeram uma função em um objeto retornar um objeto em vez de status?'.
Também mais uma fonte que torna esse comportamento explícito (na documentação da função de substituição)
Fonte: https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replace(char,%20char)
Fonte: JavaDoc de String.
fonte
A sequência de objetos - métodos em si é feita para ser "imutável". Esta ação não produz alterações: "letters.replace (" bbb "," aaa ");"
Mas atribuir dados causa alterações no conteúdo das Strings:
// O código de hash da string Object não muda.
fonte
Se
HELLO
é sua String, você não pode mudarHELLO
paraHILLO
. Essa propriedade é chamada propriedade de imutabilidade.Você pode ter várias variáveis String de ponteiro para apontar HELLO String.
Mas se HELLO for char Array, você poderá alterar HELLO para HILLO. Por exemplo,
As linguagens de programação possuem variáveis de dados imutáveis, para que possam ser usadas como chaves no par de chaves e valores.
fonte
Eu explicaria isso com um exemplo simples
na matriz de caracteres, podemos executar operações como imprimir apenas as últimas três letras usando a iteração da matriz; mas na string precisamos criar um novo objeto String e copiar a substring necessária e seu endereço estará no novo objeto string.
por exemplo
então s2 terá "hel";
fonte
String em Java em Immutable e Final significa apenas que não pode ser alterado ou modificado:
Caso 1:
Caso 2:
fonte
Como String é imutável, portanto, as alterações não ocorrerão se você não atribuir o valor retornado da função à string.Então, em sua pergunta, atribua o valor da função swap ao valor retornado a s.
s = swap (s, n1, n2); o valor da string s será alterado.
Eu também estava obtendo o valor inalterado quando estava escrevendo o programa para obter algumas seqüências de permutações (embora não esteja fornecendo todas as permutações, mas isso é, por exemplo, para responder à sua pergunta)
Aqui está um exemplo.
Mas eu não estava obtendo os valores permutados da string acima do code.So, eu atribui o valor retornado da função swap à string e obtive valores alterados da string. depois de atribuir o valor retornado, obtive os valores permutados da string.
fonte
Produzirá colocar algo assim
1419358369 1419358369
103056 65078777
O objetivo do objeto Imutável é que seu valor não deva ser alterado depois de atribuído. Ele retornará um novo objeto sempre que você tentar alterá-lo com base na implementação. Nota: Stringbuffer em vez de string pode ser usado para evitar isso.
Para sua última pergunta: u terá uma referência e duas strings no pool de strings. Exceto que a referência apontará para m! Ss! Ss! Pp!
fonte