De acordo com a String # intern () , o intern
método deve retornar a String do pool de String se a String for encontrada no pool de String, caso contrário, um novo objeto de string será adicionado ao pool de String e a referência dessa String será retornada.
Então eu tentei isso:
String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();
if ( s1 == s2 ){
System.out.println("s1 and s2 are same"); // 1.
}
if ( s1 == s3 ){
System.out.println("s1 and s3 are same" ); // 2.
}
Eu esperava que s1 and s3 are same
fosse impresso como s3 está internado e s1 and s2 are same
não será impresso. Mas o resultado é: ambas as linhas são impressas. Portanto, isso significa que, por padrão, as constantes String são internadas. Mas, se é assim, por que precisamos do intern
método? Em outras palavras, quando devemos usar esse método?
java
string
string-interning
Rakesh Juyal
fonte
fonte
intern
como método público. Não deveríamos terintern
como método privado, para que ninguém pudesse ter acesso a ele. Ou existe algum objetivo desse método?Respostas:
Java internamente automaticamente literais de String. Isso significa que, em muitos casos, o operador == parece funcionar para Strings da mesma maneira que para ints ou outros valores primitivos.
Como a internação é automática para literais de String, o
intern()
método deve ser usado em Strings construídas comnew String()
Usando seu exemplo:
retornará:
Em todos os casos, além da
s4
variável, cujo valor foi criado explicitamente usando onew
operador e onde ointern
método não foi usado no resultado, é uma única instância imutável que está sendo retornada pelo conjunto constante de cadeias da JVM .Consulte JavaTechniques "String Equality and Interning" para obter mais informações.
fonte
String s1 = "Rakesh";
primeiro OB1String s4 = new String("Rakesh");
Segundo OB2 Então, o resto de (s2, s3, s5) faz referência ao mesmo objeto (OB1) criado em 'string Pool'. Posso dizer que o.intern()
método usado para impedir a criação de um novo objeto se a mesma string disponível emstring pool
If minha suposição está errada, então me dê uma direção.Em um projeto recente, algumas estruturas de dados enormes foram configuradas com dados lidos em um banco de dados (e, portanto, não constantes / literais de String), mas com uma enorme quantidade de duplicação. Era um aplicativo bancário, e coisas como os nomes de um conjunto modesto (talvez 100 ou 200) corporações apareciam em todo lugar. As estruturas de dados já eram grandes e, se todos esses nomes de corp tivessem sido objetos únicos, eles teriam excedido a memória. Em vez disso, todas as estruturas de dados tinham referências aos mesmos objetos de 100 ou 200 String, economizando muito espaço.
Outra pequena vantagem das Strings internas é que
==
elas podem ser usadas (com sucesso!) Para comparar Strings, se todas as strings envolvidas tiverem a garantia de serem internadas. Além da sintaxe mais enxuta, isso também é um aprimoramento de desempenho. Mas, como outros já apontaram, isso acarreta um grande risco de introdução de erros de programação; portanto, isso deve ser feito apenas como uma medida desesperada de último recurso.A desvantagem é que a internação de uma String leva mais tempo do que simplesmente jogá-la na pilha e que o espaço para as Strings internas pode ser limitado, dependendo da implementação do Java. É melhor fazer isso quando você lida com um número razoável conhecido de Strings com muitas duplicações.
fonte
The downside is that interning a String takes more time than simply throwing it on the heap, and that the space for interned Strings may be limited
mesmo que você não use o método interno para constante String, ele será internado automaticamente.==
cordas embora.Quero adicionar meus 2 centavos no uso
==
com seqüências de caracteres internas.A primeira coisa que
String.equals
faz éthis==object
.Portanto, embora haja algum ganho minúsculo de desempenho (você não está chamando um método), do ponto de vista do mantenedor, o uso
==
é um pesadelo, porque algumas seqüências de caracteres internas tendem a se tornar não-internas.Portanto, sugiro não confiar no caso especial de
==
para seqüências de caracteres internas, mas sempre useequals
como Gosling pretendia.EDIT: internado tornando-se não internado:
Na versão 2.0, o mantenedor decidiu tornar
hasReferenceVal
público, sem entrar em muitos detalhes, que espera uma matriz de seqüências internas.Agora você tem um bug, que pode ser muito difícil de encontrar, porque na maioria dos casos a matriz contém valores literais e, às vezes, uma string não literal é usada. Se
equals
fosse usado em vez de==
,hasReferenceVal
continuaria funcionando. Mais uma vez, o ganho de desempenho é minúsculo, mas o custo de manutenção é alto.fonte
Literais e constantes de string são internados por padrão. Ou seja,
"foo" == "foo"
(declarado pelos literais String), masnew String("foo") != new String("foo")
.fonte
intern
,String literals and constants are interned by default
:, está correto.new String("foo")
-> Aqui, um literal "foo" de String é criado no pool de String e um no heap, para que sejam criados 2 objetos no total.Aprenda Java String Intern - uma vez por todas
Strings em java são objetos imutáveis por design. Portanto, dois objetos de sequência, mesmo com o mesmo valor, serão objetos diferentes por padrão. No entanto, se desejarmos economizar memória, poderemos indicar o uso da mesma memória por um conceito chamado string intern.
As regras abaixo ajudarão você a entender o conceito em termos claros:
Exemplo:
Nota: Os casos motivacionais para estagiário de string não são discutidos aqui. No entanto, a economia de memória será definitivamente um dos objetivos principais.
fonte
você deve distinguir dois períodos de tempo, que são tempo de compilação e tempo de execução. por exemplo:
por um lado, no exemplo 1, descobrimos que todos os resultados são retornados verdadeiros, pois, no tempo de compilação, a jvm colocará o "teste" no conjunto de cadeias literais, se a jvm find "test" existir, então ele usará o existente, no exemplo 1, as seqüências de "teste" são todas apontadas para o mesmo endereço de memória, portanto o exemplo 1 retornará verdadeiro. por outro lado, no exemplo 2, o método de substring () é executado no tempo de execução, no caso de "test" == "! test" .substring (1), o pool criará dois objetos de string " test "e"! test ", portanto, são objetos de referência diferentes; portanto, este caso retornará false, no caso de" test "=="! test ".substring (1) .intern (), o método intern ( ) colocará ""! test ".substring (1)" no pool de cadeias literais,
fonte
http://en.wikipedia.org/wiki/String_interning
o interning de string é um método de armazenar apenas uma cópia de cada valor distinto de string, que deve ser imutável. As cadeias internas tornam algumas tarefas de processamento de cadeias mais eficientes em termos de tempo ou espaço, exigindo mais tempo quando a cadeia é criada ou internada. Os valores distintos são armazenados em um conjunto interno de cadeias.
fonte
Strings Internas evitam Strings duplicadas. Internar economiza RAM às custas de mais tempo de CPU para detectar e substituir seqüências de caracteres duplicadas. Há apenas uma cópia de cada String que foi internada, não importa quantas referências apontem para ela. Como Strings são imutáveis, se dois métodos diferentes usam acidentalmente a mesma String, eles podem compartilhar uma cópia da mesma String. O processo de conversão de Strings duplicadas em compartilhadas é chamado interning.String.intern () fornece o endereço da String canônica principal. Você pode comparar Strings internadas com simple == (que compara ponteiros) em vez de iguaisque compara os caracteres da String, um por um. Como Strings são imutáveis, o processo interno é livre para economizar espaço, por exemplo, não criando um literal String separado para "pot" quando ele existe como uma substring de algum outro literal, como "hippopotamus".
Para ver mais http://mindprod.com/jgloss/interned.html
fonte
RESULTADO
fonte
Quando duas strings são criadas independentemente,
intern()
permite compará-las e também ajuda na criação de uma referência no pool de strings, se a referência não existia antes.Quando você usa
String s = new String(hi)
, o java cria uma nova instância da string, mas quando você usaString s = "hi"
, o java verifica se há uma instância da palavra "oi" no código ou não e, se existir, apenas retorna a referência.Como a comparação de strings é baseada em referência,
intern()
ajuda na criação de uma referência e permite comparar o conteúdo das strings.Quando você usa
intern()
o código, ele limpa o espaço usado pela string referente ao mesmo objeto e apenas retorna a referência do mesmo objeto já existente na memória.Mas no caso de p5 quando você estiver usando:
Somente o conteúdo de p3 é copiado e p5 é criado recentemente. Portanto, não é internado .
Portanto, a saída será:
fonte
fonte
O método string intern () é usado para criar uma cópia exata do objeto string do heap no pool constante de strings. Os objetos de cadeia no conjunto constante de cadeias são internados automaticamente, mas os objetos de cadeia na pilha não são. O principal uso da criação de estagiários é economizar espaço de memória e realizar uma comparação mais rápida de objetos de sequência.
Fonte: O que é string intern em java?
fonte
Como você disse, esse
intern()
método de string primeiro encontrará no pool de String, se encontrar, retornará o objeto que aponta para ele ou adicionará uma nova String ao pool.O
s1
es2
dois objetos que apontam para a piscina String "Olá", e usando"Hello".intern()
vai achar ques1
es2
. Então"s1 == s3"
retorna true, bem como para os3.intern()
.fonte
Usando a referência de objeto de heap, se queremos obter a referência de objeto de pool constante de string correspondente , devemos procurar intern ()
Vista pictórica
Etapa 1: o objeto com dados 'Rakesh' é criado no pool constante de heap e string. Também s1 está sempre apontando para o objeto heap.
Etapa 2: usando a referência de objeto de pilha s1, estamos tentando obter a referência de objeto de pool constante de string correspondente s2, usando intern ()
Etapa 3: criar intencionalmente um objeto com dados 'Rakesh' no pool constante de strings, referenciado pelo nome s3
Como operador "==" destinado à comparação de referência.
Ficando falso para s1 == s2
Obtendo a verdade para s2 == s3
Espero que esta ajuda!
fonte