Resposta da questão

Essa questão eu retirei de um simulado bastante conhecido por aqui, gostaria de saber a opinião de vcs quanto a resposta. Após algumas participações eu volto e posto a resposta apresentada e o nome do simulado, para não influenciar nas respostas da galera.

Given:
public String makinStrings() {
String s = “Fred”;
s = s + “47”;
s = s.substring(2, 5);
s = s.toUpperCase();
return s.toString();
}
How many String objects will be created when this method is invoked?
A. 1
B. 2
C. 3
D. 4
E. 5
F. 6

To estudando para SJCP 5.0 . Então, pra mim, acho q é a resposta C pq String s foi atualizado 3x.

3x.

A resposta correta é 5.

Given:
public String makinStrings() {
String s = “Fred”;
s = s + “47”;
s = s.substring(2, 5);
s = s.toUpperCase();
return s.toString();
}

Primeiro objeto criado s—> Fred
Segundo objeto criado s—>Fred47
Terceiro objeto criado s —>ed4
Quarto objeto criado s----> ED4

Eu acho que é 4 objetos

E. 5

Fred
47
Fred47
ed4
ED4

Resposta E.

tem razao 5 objetos

Valew galera vcs me ajudaram muito. Na minha opinião seriam criadas 5 Strings, sendo elas já mostradas pelo colega bruceramone. Acontece que a resposta do simulado Killer dá como certa a alternativa C, ou seja, apenas 3 objetos. Mas depois das opiniões aqui expostas acredito que o mesmo esteja errado.

A resposta é 3.

 String s = "Fred"; -> isto usa um objeto que está no pool de strings; não cria um novo objeto
s = s + "47"; -> isto cria um novo objeto "Fred47"
s = s.substring(2, 5); -> isto cria um novo objeto "ed4"
s = s.toUpperCase(); -> isto cria um novo objeto "ED4"
return s.toString();  -> isto simplesmente retorna o próprio objeto ED4; não cria um novo objeto

Mas esse tipo de questões é capciosa porque na prova de certificação não cai pool de strings.
Outra coisa capciosa é que se a string original fosse "FRED" e se você estivesse usando o Java da Sun, toUpperCase só cria um novo objeto se ele for uma modificação (ou seja, se a entrada for "ed4", ele cria um novo objeto "ED4", mas se a entrada fosse "ED4" - e a saída é igual à entrada - toUpperCase não cria um novo objeto.)
Então você teria 2 e não 3 objetos String novos. Mas isso você só fica sabendo se ler o fonte do JDK, o que obviamente não é cobrado pela prova.

Thingol, a linha:

String s = “Fred”;

Cria o objeto e coloca no pool antes desse método ser executado?

public String makinStrings() { String s = "Fred" //Cria a String Fred (1); s = s + "47" //Cria a String 47 (2) e a String Fred47 (3); s = s.substring(2, 5) //Cria a String ed4 (4); s = s.toUpperCase() //Cria a Sttring ED4 (5); return s.toString(); }

[quote=thingol]A resposta é 3.

String s = "Fred"; -> isto usa um objeto que está no pool de strings; não cria um novo objeto s = s + "47"; -> isto cria um novo objeto "Fred47" s = s.substring(2, 5); -> isto cria um novo objeto "ed4" s = s.toUpperCase(); -> isto cria um novo objeto "ED4" return s.toString(); -> isto simplesmente retorna o próprio objeto ED4; não cria um novo objeto [/quote]

String s = "Fred"; -> isto usa um objeto que está no pool de strings; não cria um novo objetoMas para o objeto estar no pool não seria necessário ser criado a primeira vez para ser inserido lá? Na questão não mostra nenhuma String sendo criada anteriormente.

s = s + "47"; -> isto cria um novo objeto "Fred47"A String "Fred47" é formada através da concatenação de duas outras Strings, uma que nesse momento já está o pool ("Fred") e a outra é a String ("47") que após a execução dessa linha estará perdida pois nenhuma variável faz referência a ela.

Estou me baseando em uma explicação que usa um exemplo parecido com essa questão presente no livro da Kathy para Certificação cap. 6 pág.241.

Spring s1 = "spring "; String s2 = s1 + "summer "; s1.concat("fall "); s2.concat(s1); s1+= "winter "; System.out.println(s1+ " " + s2);
Aqui ela diz que foram criados 8 objetos String.

Quando você diz:

String s = “Fred”;

o que ocorreu?

  1. Você obteve uma referência para um objeto da classe X, que contém o método makingStrings

  2. Isso requer que a classe X seja carregada. A JVM, ao carregar a classe X para poder chamar o método makingStrings, pega sua tabela de constantes (que inclui a string “Fred”), e interna a string “Fred” no pool. Note que isso é feito apenas quando a classe é carregada E o método é chamado PELA PRIMEIRA VEZ.

  3. A seguir, a JVM interpreta (ou compila, se você estiver usando -Xcomp, que força a compilação de todo o código sem que haja uma prévia interpretação) o método makingStrings.

  4. Nesse instante, a string já foi criada, e a linha “s = “Fred”” simplesmente obtém uma referência a uma string que está no pool; essa linha NÃO CRIA uma nova string.

  5. Quando você faz s = s + “47”, está usando uma string do pool (“Fred”) e concatenando com outra string do pool (“47”), o que resulta em apenas mais uma string. (A rigor, um objeto StringBuffer ou StringBuilder, dependendo da versão do Java, também é criado aqui, assim como um objeto char[]; mas estamos falando apenas de Strings).

  6. Vamos ver quantos objetos foram criados no seu exemplo:

 String s1 = "spring ";   // usa 1 do pool
 String s2 = s1 + "summer ";   // usa 1 do pool, cria um objeto StringBuffer e um String - aqui temos 1 objeto String
 s1.concat("fall ");   // aqui foi usado um do pool, e criado um objeto String, que foi perdido
 s2.concat(s1);  // aqui foi criado um objeto String, que foi perdido
 s1+= "winter ";   // aqui foi criado um objeto String, mas ele não foi perdido (há uma referência para ele em s1)
 System.out.println(s1+ " " + s2);  // aqui foi criado um StringBuffer, e o resultado da concatenação é uma nova string - aqui temos o 5. objeto string.

Há a criação pelas linhas que você vê de 5 objetos String, e mais 3 que já estavam no pool. O total é realmente 8 se você contar a criação de objetos ANTES da execução desse código que você está vendo aí.

[quote=thingol]Quando você diz:

String s = “Fred”;

o que ocorreu?

  1. Você obteve uma referência para um objeto da classe X, que contém o método makingStrings

  2. Isso requer que a classe X seja carregada. A JVM, ao carregar a classe X para poder chamar o método makingStrings, pega sua tabela de constantes (que inclui a string “Fred”), e interna a string “Fred” no pool. Note que isso é feito apenas quando a classe é carregada E o método é chamado PELA PRIMEIRA VEZ.

  3. A seguir, a JVM interpreta (ou compila, se você estiver usando -Xcomp, que força a compilação de todo o código sem que haja uma prévia interpretação) o método makingStrings.

  4. Nesse instante, a string já foi criada, e a linha “s = “Fred”” simplesmente obtém uma referência a uma string que está no pool; essa linha NÃO CRIA uma nova string.

  5. Quando você faz s = s + “47”, está usando uma string do pool (“Fred”) e concatenando com outra string do pool (“47”), o que resulta em apenas mais uma string. (A rigor, um objeto StringBuffer ou StringBuilder, dependendo da versão do Java, também é criado aqui, assim como um objeto char[]; mas estamos falando apenas de Strings).

  6. Vamos ver quantos objetos foram criados no seu exemplo:

 String s1 = "spring ";   // usa 1 do pool
 String s2 = s1 + "summer ";   // usa 1 do pool, cria um objeto StringBuffer e um String - aqui temos 1 objeto String
 s1.concat("fall ");   // aqui foi usado um do pool, e criado um objeto String, que foi perdido
 s2.concat(s1);  // aqui foi criado um objeto String, que foi perdido
 s1+= "winter ";   // aqui foi criado um objeto String, mas ele não foi perdido (há uma referência para ele em s1)
 System.out.println(s1+ " " + s2);  // aqui foi criado um StringBuffer, e o resultado da concatenação é uma nova string - aqui temos o 5. objeto string.

Há a criação pelas linhas que você vê de 5 objetos String, e mais 3 que já estavam no pool. O total é realmente 8 se você contar a criação de objetos ANTES da execução desse código que você está vendo aí.

[/quote]
Perfeito! Agora não me resta a menor dúvida. Alguns colegas já tinham até colocado 3 objetos como resposta mas nenhum deles explicou o pq, só tive explicações para outras quantidades de objetos. Agradeço o tempo despendido para elaboração da explicação. Muito Obrigado!

Eu também agradeço pelas explicações do thingol, achava que eram 5 objetos.

Acredito que foram criados 5 objetos…
essa questão do pool deve ser abstraída…até pq não mostra nenhum codigo anterior a criando…
portanto…pra todos os efeitos…ela estava sendo criada naquele momento.