JavaRush /Blogue Java /Random-PT /Tradução: Criando objetos String em Java - usando "" ou c...
FellowSparrow
Nível 12
Lvov

Tradução: Criando objetos String em Java - usando "" ou construtor?

Publicado no grupo Random-PT
Original: Criar string Java usando “” ou construtor? Por X Wang Tradução: Criando Objetos String em Java - UsoEm Java, uma string pode ser criada usando dois métodos:
String x = "abc";
String y = new String("abc");
Qual é a diferença entre usar aspas duplas e usar um construtor?

1. Aspas duplas vs. Construtor

Esta questão pode ser respondida observando dois exemplos simples. Exemplo 1:
String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
a==btrue porque aambos bse referem ao mesmo objeto - uma string declarada como literal (string literal abaixo) na área do método (remetemos o leitor à fonte em nosso recurso: Top 8 diagramas para entender Java , diagrama 8). Quando a mesma string literal é criada mais de uma vez, apenas uma cópia da string é armazenada na memória, apenas uma instância dela (no nosso caso "abcd"). Isso é chamado de "estágio de string". Todas as constantes de string processadas em tempo de compilação são automaticamente internadas em Java. Exemplo 2:
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True
c==dfalso porque cse dreferem a dois objetos diferentes na memória (na pilha). Objetos diferentes sempre têm referências diferentes. Este diagrama ilustra as duas situações descritas acima: Tradução: Criando Objetos String em Java - Uso

2. Internando strings durante a execução do programa

O autor agradece a LukasEder (o comentário abaixo é dele): O internamento de strings também pode ocorrer durante a execução do programa, mesmo que duas strings sejam criadas usando construtores:
String c = new String("abcd").intern();
String d = new String("abcd").intern();
System.out.println(c == d);  // Now true
System.out.println(c.equals(d)); // True

3. Quando usar aspas duplas e quando usar construtores

Devido ao fato de o literal "abcd" ser sempre do tipo String, o uso de um construtor criará um objeto adicional desnecessário. Portanto, aspas duplas devem ser usadas se você precisar apenas criar uma string. Se você realmente precisar criar um novo objeto no heap, deverá usar um construtor. Os casos de uso são mostrados aqui (original) . (Forneço o texto traduzido abaixo. Mas ainda assim recomendo fortemente que você se familiarize com o código dos comentaristas neste link.)

O método substring() no JDK 6 e JDK 7

O método substring() no JDK 6 e JDK 7 por X Wang O método substring(int beginIndex, int endIndex)no JDK 6 e JDK 7 é diferente. Conhecer essas diferenças pode ajudá-lo a usar melhor esse método. Para facilitar a leitura, a seguir substring()iremos nos referir à sintaxe completa, ou seja, substring(int beginIndex, int endIndex).

1. O que substring() faz?

O método substring(int beginIndex, int endIndex)retorna uma string que começa com o caractere número beginIndexe termina com o caractere número endIndex-1.
String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);
Saída:
bc

2. O que acontece quando substring() é chamado?

Você deve saber que, devido à imutabilidade x, ao atribuir x o resultado de x.substring(1,3), xele aponta para uma linha completamente nova (ver diagrama): Tradução: Criando Objetos String em Java - UsoNo entanto, este diagrama não está completamente correto; não demonstra o que realmente está acontecendo na pilha. O que realmente acontece quando é chamado substring()difere no JDK 6 e no JDK 7.

3. substring() no JDK 6

O tipo string é suportado pelo tipo array char. No JDK 6, a classe Stringcontém 3 campos: char value[], int offset, int count. Eles são usados ​​para armazenar a matriz real de caracteres, o índice do primeiro caractere da matriz, o número de caracteres na linha. Quando o método é chamado substring(), ele cria uma nova linha, mas o valor da variável ainda aponta para o mesmo array no heap. A diferença entre duas strings é o número de caracteres e o valor do índice do caractere inicial na matriz. Tradução: Criando Objetos String em Java - UsoO código abaixo é simplificado e contém apenas o básico para demonstrar o problema.
//JDK 6
String(int offset, int count, char value[]) {
	this.value = value;
	this.offset = offset;
	this.count = count;
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

4. Problema causado por substring() no JDK 6

Se você tem uma string MUITO longa, mas só precisa de uma pequena parte dela, que você obtém sempre que usa substring(). Isso causará problemas de execução, pois você só precisa de uma pequena parte, mas ainda terá que armazenar a string inteira. Para JDK 6, a solução é o código abaixo, que converterá a string em uma substring real:
x = x.substring(x, y) + ""
O usuário STepeR formulou uma pergunta (veja seu comentário) e pareceu necessário acrescentar o ponto 4. "Problema causado substring()no JDK 6" é um exemplo mais extenso. Espero que esta seja a resposta e ajude outras pessoas a descobrir rapidamente qual é o problema. Aqui está o código:
String a = "aLongLongString";
String b = a.substring(1, 2);
String c = a.substring(2, 6);
Portanto, no JDK 7 b, objetos сdo tipo a Stringcriados pela chamada de um método substring()em um objeto do tipo a Stringfarão referência a dois arrays recém-criados no heap - Lfor b, ongLfor c. Esses dois novos arrays serão armazenados no heap JUNTO com o array original aLongLongStringreferenciado por a. Aqueles. a matriz original não desaparece em lugar nenhum. Agora vamos retornar ao JDK 6. No JDK 6, um heap contém um único array aLongLongString. Depois de executar as linhas de código
String b = a.substring(1, 2);
String c = a.substring(2, 6);
os objetos breferem-se cao mesmo array no heap, correspondente ao objeto a: b- aos elementos do 1º ao 2º índice, c- aos elementos do 2º ao 6º índice (a numeração começa em 0, lembrete). Aqueles. Obviamente, qualquer acesso adicional às variáveis b​​ou c no JDK 6 resultará, na verdade, na “contagem” dos elementos desejados do array original no heap. No JDK 7, qualquer acesso adicional a variáveis b​​ou c causará um acesso aos arrays menores necessários que já foram criados e “vivos” no heap. Aqueles. Claramente, o JDK 7 usa fisicamente mais memória em situações como esta. Mas vamos imaginar uma opção possível: certas substrings da variável são atribuídas às variáveis ​​​​e b, no futuro, todos usarão apenas elas - objetos e . Ninguém mais simplesmente acessa a variável a; não há referências a ela (é isso que o autor do artigo quer dizer). Como resultado, em algum momento o coletor de lixo é acionado e (na forma mais geral, é claro) temos 2 situações diferentes: JDK 6 : o objeto é destruído (lixo coletado) , MAS - o enorme array original na pilha está vivo; é constantemente usado e . JDK 7: o objeto a é destruído junto com o array original no heap. Este é o ponto do JDK 6 que pode levar a um vazamento de memória. cabcabc

5. substring() no JDK 7

O método foi aprimorado no JDK 7. No JDK 7, substring()ele cria um novo array no heap. Tradução: Criando Objetos String em Java - Uso
//JDK 7
public String(char value[], int offset, int count) {
	//check boundary
	this.value = Arrays.copyOfRange(value, offset, offset + count);
}

public String substring(int beginIndex, int endIndex) {
	//check boundary
	int subLen = endIndex - beginIndex;
	return new String(value, beginIndex, subLen);
}
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION