Pergunta

Eu vejo um monte de código legado como esta:

class A {
    public static final String CONSTANT = "value".intern();
    ...
}

Eu não vejo nenhuma razão para o interno (), como no Javadoc pode ler: "Todos os strings literais e expressões constantes valorizado cordas estão internados" Existe alguma intenção deste, talvez em revisões anteriores da língua?

Foi útil?

Solução

Esta é uma técnica para garantir que CONSTANT não é realmente uma constante.

Quando o compilador Java vê uma referência a um static final primitivo ou String, ele insere o valor real do que constante para a classe que o utiliza. Se você alterar o valor constante na classe definindo mas não recompilar a classe usando, ele vai continuar a usar o valor antigo.

Ao chamar estagiário () na string "constante", ele não é mais considerado uma constante estático pelo compilador, então a classe usando realmente acessar o membro definição de classe em cada utilização.


JLS citações:

Outras dicas

O uso de intern() com o literal string constante é um desperdício de tempo como o literal já será internado conforme especificado pela seção 3.10. 5. string literais de O Java® Specification Language .

Citando Java SE 8 Edição:

Além disso, uma cadeia de caracteres refere-se sempre ao mesmo exemplo de corda classe. Isso ocorre porque strings literais - ou, mais genericamente, cordas que são os valores das expressões constantes (§15.28) -. São "internado" para instâncias exclusivas de compartilhamento, usando o método String.intern

Eu acho que o codificador não apreciar este fato.

Editar:

Como kdgregory tem fora apontado há um impacto sobre a forma como esta constante pode ser embutido.

1 - https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls -3.10.5

Um tempo atrás eu estagiário () ed todas as cordas provenientes de arquivos de classe (para um analisador classfile). Intern () O ING fez o uso do programa menos memória (não neste caso, como outros apontaram), mas ele fez lento o programa para baixo significativamente (acho que demorou 4 segundos para analisar todos rt.jar e que a mudança colocá-lo mais de 8 segundos). Olhando para ele na época (foi JDK 1.4 eu acho) o estagiário () código é muito feio e mais lento que em provavelmente precisa ser.

Se eu fosse para considerar chamar estagiário () no meu código eu primeiro perfil sem estagiário () e, em seguida, o perfil com estagiário () tanto para a memória e velocidade e ver qual é o "pior" para a mudança.

Eu tenho usado estagiário () para "bloqueio". Por exemplo, digamos que eu tenho um "repositório" de "registros comerciais". Enquanto eu editar e atualizar um comércio que eu quero para bloquear o comércio; Eu poderia, em vez bloquear na tradeId.intern () para que eu não precisa se preocupar com clones de um comércio flutuando. Não estou certo se todo mundo gosta esse uso.

Isso pressupõe que o campo id é improvável que acidentalmente colidem com o campo id de outro objeto de domínio - um tradeId não acontece a colidir com ACCOUNT_NUMBER por exemplo, onde se pode também estar fazendo

synchronized(account.getAccountNumber().intern()) {...}

href="http://tshrestha.blogspot.com/2012/01/stringintern-and-concurrency.html"

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top