Me perguntaram em uma entrevista por que String é imutável
Eu respondi assim:
Quando criamos uma string em java como
String s1="hello";
um objeto será criado no pool de strings (hello) e s1 apontará para hello. Agora, se fizermos novamente,String s2="hello";
outro objeto não será criado, mas s2 apontaráhello
porque a JVM verificará primeiro se o mesmo objeto estiver presente no pool de cadeias ou não. Se não estiver presente, apenas um novo será criado.
Agora, se java suponha que permite mutável corda, em seguida, se mudarmos s1 para hello world
então s2 valor também será hello world
assim java String é imutável.
Alguém pode me dizer se minha resposta está certa ou errada ?
std::string
é mutável, mas eles também possuem um conjunto de cadeias de caracteres (bem, mais corretamente, um conjunto de matrizes de caracteres).Respostas:
String
é imutável por várias razões, aqui está um resumo:String
em conexões de rede, URLs de conexão de banco de dados, nomes de usuário / senhas etc. Se fossem mutáveis, esses parâmetros poderiam ser facilmente alterados.String
é usado como argumento para carregamento de classe. Se mutável, pode resultar no carregamento incorreto da classe (porque objetos mutáveis alteram seu estado).Dito isto, a imutabilidade
String
significa apenas que você não pode alterá-lo usando sua API pública. Na verdade, você pode ignorar a API normal usando reflexão. Veja a resposta aqui .No seu exemplo, se
String
era mutável, considere o seguinte exemplo:fonte
String
for mutável, o carregador de classes pegará a string passada, fará uma cópia e não alterará sua cópia. Ao pensar em um problema com mutáveisjava.lang.String
s, pense em como resolve C ++ este problema (uma vez que tem mutáveisstd::string
s.Os desenvolvedores de Java decidem que as strings são imutáveis devido ao seguinte aspecto , design, eficiência e segurança .
As seqüências de design são criadas em uma área de memória especial na pilha java conhecida como "Conjunto de String Intern". Enquanto você cria um novo String (não no caso de usar o construtor String () ou qualquer outra função String que use internamente o construtor String () para criar um novo objeto String; o construtor String () sempre cria uma nova constante de string no pool, a menos que chame a variável intern () do método que ele procura no pool para verificar se ele já existe. Se existir, retorne a referência do objeto String existente. Se a String não for imutável, alterar a String com uma referência levará ao valor errado para as outras referências.
De acordo com este artigo no DZone:
fonte
Não podemos ter certeza do que os designers de Java estavam realmente pensando ao projetar,
String
mas podemos concluir esses motivos com base nas vantagens que obtemos da imutabilidade de cadeias de caracteres, algumas das quais são1. Existência de pool constante de strings
Conforme discutido no artigo Por que a seqüência de caracteres é armazenada no pool constante de seqüências de caracteres , todo aplicativo cria muitos objetos de sequência e, a fim de salvar a JVM primeiro criando muitos objetos de sequência e depois coletando-os com lixo. A JVM armazena todos os objetos de sequência em uma área de memória separada chamada Conjunto constante de sequência e reutiliza objetos desse conjunto em cache.
Sempre que criamos um literal de cadeia, a JVM vê pela primeira vez se esse literal já está presente no pool constante ou não, e se existe, uma nova referência começará a apontar para o mesmo objeto no SCP.
No exemplo acima objeto string com o valor
Naresh
irá ser criada no SCP apenas uma vez e todas as referênciasa
,b
,c
irá apontar para o mesmo objeto, mas o que se tentarmos fazer a mudança ema
ega.replace("a", "")
.Idealmente,
a
deve ter valor ,Nresh
mas deve permanecer inalterado porque, como usuário final, estamos fazendo apenas a alteração . E sabemos , , todos estão apontando o mesmo objeto para se fazer uma mudança em , outros também devem refletir a alteração.b
c
a
a
b
c
a
Mas a imutabilidade de string nos salva desse cenário e, devido à imutabilidade do objeto de string, o objeto de string
Naresh
nunca será alterado. Portanto, quando fazemos alguma alteração noa
objeto de sequência, em vez de noNaresh
JVM, um novo objeto é atribuídoa
e, então, fazemos a alteração nesse objeto.Portanto, o pool de String só é possível devido à imutabilidade de String e se String não fosse imutável, o armazenamento em cache de objetos de string e a sua reutilização não teriam possibilidade, porque qualquer variável alteraria o valor e corromperia outros.
E é por isso que é tratado pela JVM de maneira muito especial e recebeu uma área de memória especial.
2. Segurança da linha
Um objeto é chamado de thread-safe quando vários threads estão operando nele, mas nenhum deles pode corromper seu estado e o objeto mantém o mesmo estado para todos os threads a qualquer momento.
Como nós, um objeto imutável não pode ser modificado por ninguém após sua criação, o que torna todos os objetos imutáveis protegidos por thread por padrão. Não precisamos aplicar nenhuma medida de segurança de thread, como a criação de métodos sincronizados.
Portanto, devido à sua natureza imutável, o objeto string pode ser compartilhado por vários threads e, mesmo que esteja sendo manipulado por muitos threads, não alterará seu valor.
3. Segurança
Em todas as aplicações, precisamos passar vários segredos, por exemplo, nome de usuário \ senhas do usuário, URLs de conexão e, em geral, todas essas informações são passadas como o objeto string.
Agora, suponha que se String não fosse imutável por natureza, isso causaria uma séria ameaça à segurança do aplicativo, porque esses valores podem ser alterados e, se for permitido, podem ser alterados devido a códigos escritos incorretamente ou a qualquer outra pessoa que tenha acesso às nossas referências de variáveis.
4. Carregamento de classe
Conforme discutido em Criando objetos através do Reflection em Java com exemplo , podemos usar o
Class.forName("class_name")
método para carregar uma classe na memória que novamente chama outros métodos para fazê-lo. E até a JVM usa esses métodos para carregar classes.Mas se você ver claramente todos esses métodos aceitam o nome da classe como um objeto string, portanto, Strings são usadas no carregamento da classe java e a imutabilidade fornece segurança pela qual a classe correta está sendo carregada
ClassLoader
.Suponha que se String não fosse imutável e estamos tentando carregar os
java.lang.Object
que foram alterados paraorg.theft.OurObject
entre e agora todos os nossos objetos têm um comportamento que alguém pode usar para coisas indesejadas.5. Cache de HashCode
Se pretendemos executar operações relacionadas a hash em qualquer objeto, devemos substituir o
hashCode()
método e tentar gerar um código de hash preciso usando o estado do objeto. Se o estado de um objeto está sendo alterado, significa que seu código de hash também deve mudar.Como String é imutável, o valor que um objeto de string está mantendo nunca será alterado, o que significa que seu código de hash também não será alterado, o que dá à classe String uma oportunidade de armazenar em cache seu código de hash durante a criação do objeto.
Sim, o objeto String armazena em cache seu código de hash no momento da criação do objeto, o que o torna o melhor candidato para operações relacionadas ao hash, porque o código de hash não precisa ser calculado novamente, o que economiza algum tempo. É por isso que String é usado principalmente como
HashMap
chaves.Leia mais sobre Por que a string é imutável e final em Java .
fonte
Razão mais importante de acordo com este artigo no DZone:
Espero que ajude você.
fonte
Li este post Por que a String é imutável ou final em Java e suponho que o seguinte seja o motivo mais importante:
fonte
Você está certo.
String
em java usa o conceito deString Pool
literal. Quando uma string é criada e se a string já existe no pool, a referência da string existente será retornada, em vez de criar um novo objeto e retornar sua referência.Se uma string não for imutável, alterar a string com uma referência será levar ao valor errado para as outras referências.Eu acrescentaria mais uma coisa, já que
String
é imutável, é seguro para multi-threading e uma única instância de String pode ser compartilhada em diferentes segmentos. Isso evita o uso da sincronização para segurança do encadeamento. As seqüências são implicitamentethread safe
.fonte
Classe de string
FINAL
significa que você não pode criar nenhuma classe para herdá-la, alterar a estrutura básica e tornar o Sting mutável.Outra variável de instância e métodos da classe String fornecidos são tais que você não pode alterar o
String
objeto depois de criado.O motivo pelo qual você adicionou não torna a String imutável.Tudo indica como a String é armazenada na pilha.Também o pool de strings faz a enorme diferença no desempenho
fonte
A string é fornecida como imutável pelos microssistemas Sun, porque a string pode ser usada para armazenar como chave na coleção de mapas. StringBuffer é mutável. Esse é o motivo, não pode ser usado como chave no objeto de mapa
fonte
O motivo mais importante de uma String ser imutável em Java é a consideração de segurança . Em seguida seria o cache .
Acredito que outras razões apresentadas aqui, como eficiência, concorrência, design e pool de strings, decorram do fato de que String se tornou imutável. Por exemplo. O pool de strings pode ser criado porque o String é imutável e não o contrário.
Confira a transcrição da entrevista de Gosling aqui
fonte
Além das ótimas respostas, gostaria de acrescentar alguns pontos. Como Strings, Array mantém uma referência ao início da matriz, portanto, se você criar duas matrizes
arr1
earr2
fez algo parecido comarr2 = arr1
isso, a referência será aarr2
mesma, pois aarr1
alteração do valor em uma delas resultará na alteração da outra, por exemploAlém de causar bugs no código, ele também pode (e será) explorado por usuários mal-intencionados. Suponha que você tenha um sistema que altere a senha do administrador. O usuário deve primeiro digitar o
newPassword
e, em seguida,oldPassword
se ooldPassword
mesmo foradminPass
o programa, altere a senhaadminPass = newPassword
. digamos que a nova senha tenha a mesma referência que a senha de administrador, portanto, um programador ruim pode criar umatemp
variável para reter a senha de administrador antes que os usuários insiram dados se o valoroldPassword
igual atemp
ele alterar a senha, caso contrárioadminPass = temp
. Alguém sabendo que poderia facilmente inserir a nova senha e nunca inserir a senha antiga e abracadabra, ele tem acesso de administrador. Outra coisa que eu não entendi ao aprender sobre Strings, por que a JVM não cria uma nova string para cada objeto e tem um lugar único na memória para isso? Você pode fazer isso usandonew String("str");
O motivo pelo qual você não gostaria de usar semprenew
é porque não é eficiente em termos de memória e é mais lento na maioria dos casos, leia mais .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,
Responda:
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. Variáveis de string são usadas como chaves / índices, portanto são imutáveis .
fonte
Do
Security
ponto de vista, podemos usar este exemplo prático:fonte