• Skip to primary navigation
  • Skip to content

Mauda

IT, Java and Music

Graduação   SCJP   Mestrado
  • Apresentação
  • Certificação Java
  • JPA
    • Exceptions
  • JSF
  • Versionamento
  • Contato

java.lang.String: instanciação

August 31, 2015 by Mauda Leave a Comment

Conteúdo do Post:
  1. java.lang.String – Instanciação
  2. Instanciando com Aspas Duplas
  3. Instanciando via Construtor
  4. finnaly{

Olá Pessoal, tudo bom?

Chega de falar sobre certificação :-D, vamos hoje falar sobre a classe String e as formas de realizar a sua instanciação.

java.lang.String – Instanciação

De acordo com a API da classe String, existem duas formas de iniciar uma classe String:

Java
1
2
String x = "abc";
String y = new String("abc");

O mais comum é que o desenvolvedor menos experiente na linguagem ache que uma instanciação com aspas duplas é igual a uma instanciação com o construtor da classe String. O que não é verdadeiro. Mas qual é a diferença entre utilizar aspas duplas e utilizar o construtor new?

Instanciando com Aspas Duplas

Vamos observar o seguinte código:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package br.com.mauda.string;
 
import junit.framework.Assert;
 
import org.junit.Test;
 
public class TesteString1 {
 
@Test
public void teste(){
String a = "abcd";
String b = "abcd";
Assert.assertTrue(a == b);
Assert.assertTrue(a.equals(b));
}
}

Esse teste foi construído para rodar na ferramenta JUnit. Caso não conheça a ferramenta há um tutorial aqui.

A linha 15 será verdadeira, em primeiro lugar pois é uma comparação de endereços de memória, o que nos leva a pergunta, mas como é que duas Strings diferentes podem estar no mesmo endereço de memória?

De acordo com a API da classe String temos:

Strings are constant; their values cannot be changed after they are created. Because String objects are immutable they can be shared. For example:

Java
1
String str = "abc";

is equivalent to:

Java
1
2
char data[] = {'a', 'b', 'c'};
String str = new String(data);

Traduzindo 🙂 A classe String é constante, ou seja, os valores não podem ser modificados após a sua criação, o que permite que elas possam ser compartilhadas entre vários “ponteiros” (mais detalhes sobre ponteiros, veja aqui). Assim uma String instanciada com aspas duplas é igual a instanciação de uma String via construtor de um vetor de caracteres.

Assim a Figura 01 abaixo representa o que ocorre na linha 15:

Figura 01 – Fotografia do Java Heap a partir da execução do teste da classe TesteString1.

Já a linha 16 é correta, pois é uma comparação com o método equals, o qual é sobrescrito na classe String e compara o valor dos caracteres internos, logo essa linha será verdadeira também.

Instanciando via Construtor

Vamos observar o seguinte código:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package br.com.mauda.string;
 
import junit.framework.Assert;
 
import org.junit.Test;
 
public class TesteString2 {
 
@Test
public void teste(){
String c = new String("abcd");
String d = new String("abcd");
Assert.assertTrue(c == d);
Assert.assertTrue(c.equals(d));
}
}

E agora, o que você acha, a linha 15 será verdadeira ou falsa? e a linha 16?

Vamos começar pela mais fácil a linha 16 será verdadeira, pois continua utilizando o mesmo método equals do teste anterior, logo a comparação realizada é com o conteúdo da String o que torna a linha verdadeira.

Já a linha 15 será falsa! Sim, falsa! Mas as Strings não são imutáveis e compartilhadas? Sim! Mas então por que é falsa a execução desta linha. Para isso vamos olhar a Figura 02 abaixo:

Figura 02 – Fotografia do Java Heap a partir da execução do teste da classe TesteString2

Repare que ao criar as novas instâncias via construtor elas são armazenadas em endereços de memória distintos, mas esses endereços apontam para a mesma String imutável. Lembre-se para a criar a String com o construtor, o que você precisou criar? Uma String com aspas duplas!!! Logo você está fazendo um encapsulamento de Strings, pois você criou uma String e armazenou esta dentro de outra String!

Existe uma forma de resolver esse problema, utilizando o método da classe String chamado intern(), link da API, assim o exemplo abaixo irá passar corretamente.

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package br.com.mauda.string;
 
import junit.framework.Assert;
 
import org.junit.Test;
 
public class TesteString3 {
 
@Test
public void teste(){
String c = new String("abcd").intern();
String d = new String("abcd").intern();
Assert.assertTrue(c == d);
Assert.assertTrue(c.equals(d));
}
}

A Figura 03, representa a Heap do java após a execução deste teste:

Figura 03 – Fotografia do Java Heap a partir da execução do teste da classe TesteString3

A pergunta que deve surgir é como não foram criadas as outras instâncias da classe String, conforme a Figura 02? É porque no caso do método intern o compilador Java, durante a geração dos bytecodes, remove o new String e deixa apenas a String com aspas duplas “abcd”. Assim não haverão mais 2 instâncias ocupando memória do Java.

 

finnaly{

Para finalizar, não utilize o construtor da classe String apenas irá criar um objeto a mais, pois a String que você deseja já existe em memória.

Duvidas ou sugestões? Achou outros livros que possam ser colocados aqui? Deixe seu feedback! Isso ajuda a saber a sua opinião sobre os artigos e melhorá-los para o futuro! Isso é muito importante!

Até um próximo post!

Filed Under: Java Tagged With: aspasDuplas, java.lang.String, new, Ponteiros, String

About Mauda

Mestre em Informática, Analista de Sistemas, Professor, SCJP e Baterista. Desde 2002 trabalhando no mundo Java e ensinando pessoas sobre desenvolvimento de sistemas. Mais informações

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Advertisements

Copyright © 2025 · Genesis Framework · WordPress · Log in