Esta poderia ser a pergunta mais idiota já feita, mas acho que é bastante confusa para um novato em Java.
- Alguém pode esclarecer o que se entende por imutável ?
- Por que é
String
imutável? - Quais são as vantagens / desvantagens dos objetos imutáveis?
- Por que um objeto mutável, como o
StringBuilder
preferido, é preferível a String e vice-verso?
Um bom exemplo (em Java) será realmente apreciado.
java
string
immutability
ashokgelal
fonte
fonte
Respostas:
Imutável significa que depois que o construtor de um objeto concluir a execução, a instância não poderá ser alterada.
Isso é útil, pois significa que você pode passar referências ao objeto, sem se preocupar com o fato de alguém mudar seu conteúdo. Especialmente ao lidar com simultaneidade, não há problemas de bloqueio com objetos que nunca mudam
por exemplo
Foo
não precisa se preocupar que o chamadorgetValue()
altere o texto na sequência.Se você imaginar uma classe semelhante a
Foo
, mas com um membro emStringBuilder
vez deString
membro, poderá ver que um chamadorgetValue()
poderá alterar oStringBuilder
atributo de umaFoo
instância.Também tenha cuidado com os diferentes tipos de imutabilidade que você pode encontrar: Eric Lippert escreveu um artigo de blog sobre isso. Basicamente, você pode ter objetos cuja interface é imutável, mas nos bastidores, o estado privado real dos mutables (e, portanto, não pode ser compartilhado com segurança entre os threads).
fonte
Um objeto imutável é um objeto em que os campos internos (ou pelo menos todos os campos internos que afetam seu comportamento externo) não podem ser alterados.
Há muitas vantagens em cadeias imutáveis:
Desempenho: Execute a seguinte operação:
O C subjacente para o método substring () é provavelmente algo como isto:
Observe que nenhum dos caracteres precisa ser copiado! Se o objeto String fosse mutável (os caracteres poderiam mudar mais tarde), você teria que copiar todos os caracteres, caso contrário, as alterações nos caracteres da substring serão refletidas na outra sequência posteriormente.
Simultaneidade: se a estrutura interna de um objeto imutável for válida, ela sempre será válida. Não há chance de que diferentes threads possam criar um estado inválido nesse objeto. Portanto, objetos imutáveis são seguros para threads .
Coleta de lixo: é muito mais fácil para o coletor de lixo tomar decisões lógicas sobre objetos imutáveis.
No entanto, também existem desvantagens na imutabilidade:
Desempenho: espere, pensei que você dissesse que o desempenho era uma vantagem da imutabilidade! Bem, às vezes é, mas nem sempre. Pegue o seguinte código:
As duas linhas substituem o quarto caractere pela letra "a". Não é apenas o segundo trecho de código mais legível, é mais rápido. Veja como você teria que fazer o código subjacente para foo. As substrings são fáceis, mas agora, como já existe um personagem no espaço cinco e outra coisa pode estar se referindo a foo, você não pode simplesmente mudá-lo; você precisa copiar toda a cadeia de caracteres (é claro que parte dessa funcionalidade é abstraída para funções no C subjacente real, mas o objetivo aqui é mostrar o código que é executado em um único local).
Observe que concatenar é chamado duas vezes, o que significa que toda a cadeia precisa ser repetida! Compare isso com o código C para a
bar
operação:A operação de sequência mutável é obviamente muito mais rápida.
Conclusão: Na maioria dos casos, você deseja uma sequência imutável. Mas se você precisar acrescentar e inserir muito em uma string, precisará da mutabilidade para obter velocidade. Se você deseja os benefícios de segurança e coleta de lixo da concorrência, a chave é manter seus objetos mutáveis locais para um método:
Como o
mutable
objeto é uma referência local, você não precisa se preocupar com a segurança de simultaneidade (apenas um encadeamento o toca). E como não é referenciado em nenhum outro lugar, ele é alocado apenas na pilha; portanto, é desalocado assim que a chamada de função é concluída (você não precisa se preocupar com a coleta de lixo). E você obtém todos os benefícios de desempenho de mutabilidade e imutabilidade.fonte
Passing pointers because Java is pass-by-reference
Java não é "passagem por valor"?Na verdade, String não é imutável se você usar a definição da Wikipedia sugerida acima.
O estado da string muda após a construção. Dê uma olhada no método hashcode (). A cadeia armazena em cache o valor do código de hash em um campo local, mas não o calcula até a primeira chamada de hashcode (). Essa avaliação preguiçosa do código de hash coloca String em uma posição interessante como um objeto imutável cujo estado muda, mas não se pode observar que ele mudou sem o uso de reflexão.
Portanto, talvez a definição de imutável deva ser um objeto que não se pode observar ter mudado.
Se o estado muda em um objeto imutável após a criação, mas ninguém pode vê-lo (sem reflexão), o objeto ainda é imutável?
fonte
Objetos imutáveis são objetos que não podem ser alterados programaticamente. Eles são especialmente bons para ambientes multiencadeados ou outros ambientes em que mais de um processo é capaz de alterar (alterar) os valores em um objeto.
Apenas para esclarecer, no entanto, o StringBuilder é realmente um objeto mutável, não imutável. Uma String java regular é imutável (o que significa que, uma vez criada, você não pode alterar a string subjacente sem alterar o objeto).
Por exemplo, digamos que eu tenho uma classe chamada ColoredString que possui um valor String e uma cor String:
Neste exemplo, o ColoredString é considerado mutável porque você pode alterar (alterar) uma de suas principais propriedades sem criar uma nova classe ColoredString. A razão pela qual isso pode ser ruim é, por exemplo, digamos que você tenha um aplicativo GUI com vários threads e esteja usando o ColoredStrings para imprimir dados na janela. Se você tiver uma instância do ColoredString que foi criada como
Então você esperaria que a string sempre fosse "azul". Se outro encadeamento, no entanto, conseguiu acessar essa instância e chamou
Você de repente, e provavelmente inesperadamente, agora terá uma string "Vermelha" quando quiser uma "Azul". Por esse motivo, objetos imutáveis são quase sempre preferidos ao passar instâncias de objetos. Quando você tem um caso em que objetos mutáveis são realmente necessários, normalmente você protege o objeto apenas distribuindo cópias de seu campo de controle específico.
Para recapitular, em Java, java.lang.String é um objeto imutável (não pode ser alterado depois de criado) e java.lang.StringBuilder é um objeto mutável porque pode ser alterado sem a criação de uma nova instância.
fonte
String s1 = "String antiga";
String s2 = s1;
s1 = "Nova string";
fonte
"imutável" significa que você não pode alterar o valor. Se você tiver uma instância da classe String, qualquer método que você chamar que pareça modificar o valor criará outra String.
Para preservar as mudanças, você deve fazer algo como foo = foo.sustring (3);
Imutável vs mutável pode ser engraçado quando você trabalha com coleções. Pense no que acontecerá se você usar um objeto mutável como chave para o mapa e depois alterar o valor (dica: pense em
equals
ehashCode
).fonte
java.time
Pode ser um pouco tarde, mas para entender o que é um objeto imutável, considere o seguinte exemplo da nova API Java 8 Date and Time ( java.time ). Como você provavelmente sabe que todos os objetos de data do Java 8 são imutáveis , no exemplo a seguir
Resultado:
Isso imprime o mesmo ano que a data inicial, pois
plusYears(2)
retorna um novo objeto, portanto a data antiga permanece inalterada por ser um objeto imutável. Depois de criada, você não pode modificá-la ainda mais e a variável de data ainda aponta para ela.Portanto, esse exemplo de código deve capturar e usar o novo objeto instanciado e retornado por essa chamada para
plusYears
.fonte
Eu realmente gosto da explicação do SCJP Sun Certified Programmer para Java 5 Study Guide .
fonte
Objetos imutáveis não podem ter seu estado alterado depois que eles foram criados.
Há três razões principais para usar objetos imutáveis sempre que possível, o que ajudará a reduzir o número de bugs que você introduz no seu código:
Também há outras otimizações que você poderá fazer no código quando souber que o estado de um objeto é imutável - armazenando em cache o hash calculado, por exemplo - mas essas são otimizações e, portanto, não são tão interessantes.
fonte
Um significado tem a ver com a forma como o valor é armazenado no computador. Para uma string .Net, por exemplo, significa que a string na memória não pode ser alterada. Quando você pensa que está mudando, está criando um novo string na memória e apontando a variável existente (que é apenas um ponteiro para a coleção real de caracteres em outro lugar) para a nova string.
fonte
s1="Hi"
: um objetos1
foi criado com o valor "Hi".s2=s1
: um objetos2
é criado com referência ao objeto s1.s1="Bye"
: os1
valor do objeto anterior não muda porques1
possui o tipo String e o tipo String é um tipo imutável. Em vez disso, o compilador cria um novo objeto String com o valor "Bye" e coms1
referência a ele. aqui, quando imprimirmos os2
valor, o resultado será "Oi" e não "Tchau", porque relacionados2
aos1
objeto anterior que tinha valor "Oi".fonte
Imutável significa que, uma vez que o objeto é criado, nenhum de seus membros será alterado.
String
é imutável, pois você não pode alterar seu conteúdo. Por exemplo:No código acima, a string s1 não mudou, outro objeto (
s2
) foi criado usandos1
.fonte
Imutável significa simplesmente imutável ou não modificável. Depois que o objeto string é criado, seus dados ou estado não podem ser alterados
Considere o exemplo abaixo,
Vamos ter uma idéia considerando o diagrama abaixo,
Neste diagrama, você pode ver o novo objeto criado como "Mundo do Futuro". Mas não mude "Futuro".
Because String is immutable
.s
, ainda consulte "Futuro". Se você precisar chamar "Mundo do Futuro",Por que os objetos de string são imutáveis em java?
fonte
Uma vez instanciado, não pode ser alterado. Considere uma classe da qual uma instância possa ser usada como a chave para uma hashtable ou similar. Confira as melhores práticas de Java.
fonte
Objetos imutáveis
Um objeto é considerado imutável se seu estado não puder ser alterado após a construção. A confiança máxima em objetos imutáveis é amplamente aceita como uma estratégia sólida para criar código simples e confiável.
Objetos imutáveis são particularmente úteis em aplicativos simultâneos. Como eles não podem mudar de estado, eles não podem ser corrompidos por interferência de thread ou observados em um estado inconsistente.
Os programadores costumam relutar em empregar objetos imutáveis, porque se preocupam com o custo de criar um novo objeto em vez de atualizar um objeto no local. O impacto da criação de objetos geralmente é superestimado e pode ser compensado por algumas das eficiências associadas a objetos imutáveis. Isso inclui uma sobrecarga reduzida devido à coleta de lixo e a eliminação do código necessário para proteger objetos mutáveis da corrupção.
As subseções a seguir recebem uma classe cujas instâncias são mutáveis e derivam uma classe com instâncias imutáveis. Ao fazer isso, eles fornecem regras gerais para esse tipo de conversão e demonstram algumas das vantagens de objetos imutáveis.
Fonte
fonte
Como a resposta aceita não responde a todas as perguntas. Sou forçado a dar uma resposta após 11 anos e 6 meses.
Espero que você tenha entendido um objeto imutável (porque poderíamos pensar em referências imutáveis ).
Um objeto é imutável : se criado, eles sempre representam o mesmo valor (não possui nenhum método que altere o valor).
Respeite a definição acima, que pode ser verificada no código-fonte Sting.java .
mais seguro de bugs.
mais fácil de entender.
e mais pronto para a mudança.
Limitando a pergunta Por que precisamos do StringBuilder mutável na programação? Um uso comum para isso é concatenar um grande número de seqüências de caracteres juntas, assim:
Usando cadeias imutáveis, isso faz muitas cópias temporárias - o primeiro número da cadeia ("0") é realmente copiado n vezes no decorrer da construção da cadeia final, o segundo número é copiado n-1 vezes e, portanto, em. Na verdade, custa O (n2) tempo apenas para fazer toda essa cópia, mesmo que apenas concatenássemos n elementos.
O StringBuilder foi projetado para minimizar essa cópia. Ele usa uma estrutura de dados interna simples, mas inteligente, para evitar copiar até o final, quando você solicita a String final com uma chamada toString ():
Obter um bom desempenho é uma das razões pelas quais usamos objetos mutáveis. Outra é o compartilhamento conveniente: duas partes do seu programa podem se comunicar de maneira mais conveniente, compartilhando uma estrutura de dados mutável comum.
Mais informações podem ser encontradas aqui: https://web.mit.edu/6.005/www/fa15/classes/09-immutability/#useful_immutable_types
fonte
Um objeto imutável é aquele que você não pode modificar depois de criá-lo. Um exemplo típico são literais de string.
A linguagem de programação AD, que se torna cada vez mais popular, tem uma noção de "imutabilidade" por meio da palavra-chave "invariável". Verifique o artigo deste Dr.Dobb sobre isso - http://dobbscodetalk.com/index.php?option=com_myblog&show=Invariant-Strings.html&Itemid=29 . Isso explica o problema perfeitamente.
fonte