Perguntas sobre o pool String de Java

Considere este código:

String first = "abc"; String second = new String("abc"); 

Ao usar a new palavra-chave, o Java criará a String abc novamente, certo? Isso será armazenado no heap normal ou no pool de String ? Quantos String s terminará no pool de String ?

Se você usar a new palavra-chave, um novo object String será criado. Observe que os objects estão sempre no heap – o conjunto de cadeias não é uma área de memory separada separada do heap.

O pool de strings é como um cache. Se você fizer isto:

 String s = "abc"; String p = "abc"; 

então, o compilador Java é esperto o suficiente para fazer apenas um object String , e s e p estarão se referindo a esse mesmo object String. Se você fizer isto:

 String s = new String("abc"); 

então, haverá um object String no pool, aquele que representa o literal "abc" , e haverá um object String separado, não no pool, que contém uma cópia do conteúdo do object em pool. Como String é imutável em Java, você não está ganhando nada fazendo isso; Chamar new String("literal") nunca faz sentido em Java e é desnecessariamente ineficiente.

Note que você pode chamar intern() em um object String . Isso colocará o object String no pool, se ainda não estiver lá, e retornará a referência à string agrupada. (Se já estava no pool, apenas retorna uma referência ao object que já estava lá). Veja a documentação da API para esse método para mais informações.

Veja também String interning (Wikipedia).

No bytecode , a primeira tarefa é:

   Código:
    0: ldc # 2;  // String abc
    2: astore_1

enquanto o segundo é:

    3: novo # 3;  // class java / lang / String
    6: dup
    7: ldc # 2;  // String abc
    9: invokespecial # 4;  // Método java / lang / String. "" :( Ljava / lang / String;) V

Portanto, o primeiro está no pool (na posição # 2), enquanto o segundo será armazenado no heap.

EDITAR

Como o CONSTANT_String_info armazena o índice como U2 (16 bits, sem sinal), o conjunto pode conter no máximo 2**16 = 65535 referências. No caso você se importa aqui mais limites da JVM .

Cada vez que seu código cria uma string literal

por exemplo:

 String str="Hello"; (string literal) 

a JVM verifica primeiro o pool literal de cadeias. Se a cadeia já existir no conjunto, uma referência à instância em pool será retornada. Se a string não existir no pool, um novo object String instanciará e, em seguida, será colocado no pool. Java pode fazer essa otimização, pois as strings são imutáveis ​​e podem ser compartilhadas sem medo de corrupção de dados

 String strObject = new String("Java"); 

e

 String strLiteral = "Java"; 

Ambas as expressões fornecem objects String, mas há uma diferença sutil entre eles. Quando você cria o object String usando o operador new (), ele sempre cria um novo object na memory heap. Por outro lado, se você criar um object usando a syntax literal de string, por exemplo, “Java”, ele pode retornar um object existente do conjunto String (um cache do object String no espaço Perm gen, que agora é movido para o espaço heap na liberação recente do Java) , se já existe.

A única vez que você deve usar o novo String (foo) é quando você quer quebrar ==, o que é um caso estranho, ou quando foo é uma substring de uma string muito maior que tem um tempo de vida limitado, como

 String mystring; { String source = getSomeHeinouslyLargeString(); mystring = new String(source.substring(1,3)); } 

Embora tarde, pode ser útil para alguém ainda se deparar com isso:

 String first = "abc"; //One instance object in pool created. Instance variable “first” refers/points to pooled object String second = new String("abc"); //One instance object in heap created. Object in pool creation step will be skipped on account of first statement. 

Então, no total, 2 objects de instância serão criados. Um na piscina e outro na pilha

Explicação detalhada

String primeiro = “abc”;

Aqui um object string com o conteúdo “abc” criado no pool. A variável de instância “primeiro” apontará para o object pool com o conteúdo “abc”.

String second = new String (“abc”);

Aqui outro object de string com conteúdo “abc” será criado na pilha. A variável de instância “second” apontará para o object heap com o conteúdo “abc”. Um object de string com criação de conteúdo “abc” no pool será ignorado na primeira instrução. Razão abaixo.

Motivos

Se a declaração anterior (String first = “abc”) não existir com o mesmo conteúdo, geralmente com a palavra-chave “new”, serão criados dois objects string no heap (pool externo) e o outro no pool (um subconjunto) de heap). Além disso, a variável de instância “second” deve apontar apenas para o object heap, independentemente de os objects estarem no pool ou não.

Agora, por conta da presença de uma instrução anterior (String first = “abc”;) com o mesmo conteúdo da nova String (“abc”), apenas um object (com conteúdo “abc”) é retido no pool. Portanto, por conta da primeira instrução, a segunda instrução terá apenas 1 object criado em vez de 2 e esse object está na pilha. A criação do object de pool será ignorada.

 //Additional Test on the concept System.out.println(first==second); //returns false. Because first points to pool object while second points to heap object. And both objects are different (on account of different memory locations). second = second.intern(); //After interning, second now points to pool object. Note: intern is used so that reference variable points to pool area object and not heap object. Clearly it is applicable when we use new keyword. System.out.println(first==second); //returns true. Because now both first and second objects now points to same pool object. 
 String first = "abc"; String second = new String("abc"); 

No primeiro caso, apenas um object será criado no Pool. No segundo caso, dois objects criarão um no pool (se isso não existir anteriormente no Pool) e um no heap.

Quando você está passando qualquer valor com aspas duplas ex: “abc” você está criando um object no pool e passando para o construtor de string para criar um novo object com o mesmo valor no heap.

Se você viu o construtor de string, poderá ver que ele aceita uma string. O que é essa cadeia? Antes da criação, o que é esse object de string. Não é nada, mas um object armazenado no pool String Constant.