dúvida String

26 respostas
giselezr

Oi pessoal

observe o codigo:

public static String makinStrings() {
        String s = "Fred";
        s = s + "47";
        s = s.substring(2, 5);
        s = s.toUpperCase();
        return s.toString();
    }

Quantos objetos String será criado quando este método é invocado?
a resposta é certa é 3, porem pelos meus calculos seriam 5.
1 “fred”, 2 “47”, 3 “fred47”, 4 “ed4” e 5 “ED4”

alguem pode me explicar?

abraço

26 Respostas

douglaskd

o seguinte código funciona da mesma maneira…

public static String makinStrings() { String s = "Fred"; //1 houve um new escondido no autoboxing, o java internamente faz isso: string s = new string("fred"); s = s + "47"; //2 // houve um new escondido no "47" - autoboxing, o java internamente fez: s = s + new string("47"); s = s.substring(2, 5); //3 // há um new string() dentro do método substring. s.toUpperCase(); // o método Uppecase não cria uma nova string, e sim altera a própria return s; // tostring() retornaria o próprio objeto que ja é uma string }

resposta final: 3 objetos do tipo string foram criados

desculpe as classes em minusculo, meu teclado esta com problemas… :slight_smile:

giselezr

altera a string? mas ela não é imultável?

e na parte s = s + “47”; não deveria criar a string “47” depois outra com “Fred” + “47” = Fred47 ?

abraço

douglaskd

tem razão.

seriam 4,

s.toUppercase() não funciona mesmo, ele retorna uma string…

fiquei confuso também

giselezr

huahuhaah

tá sinistro…

JuniorMaia

são criadas 4 Strings, até onde eu percebi! oO

Rodrigo_Sasaki

Eu também vi 4 Strings, aonde você viu que são somente 3?

giselezr

o teste killer disse que são 3.
não dá de anexar imagem?

Rodrigo_Sasaki

Na caixa de texto onde você escreve a resposta existem 2 botões, “Options” e “Attachments”

no attachments você pode colocar a imagem.

Só pra perguntar mesmo, você sabe que o TestKiller é ilegal, né ?

giselezr

sério?
não sabia, ai meu Deus…

Rodrigo_Sasaki

Sério, ele é a cópia da prova, portanto é ilegal.

se você está estudando existem vários simulados bacanas como os da Enthuware.

esse é pago, mas existem outros que são gratuitos, agora TestKiller é pura sacanagem hehehe

mapleplayer

Foram criadas 5 Strings

public static String makinStrings() {  
       String s = "Fred";  // Fred
       s = s + "47";  // Fred47 e 47
       s = s.substring(2, 5);  // ed4
       s = s.toUpperCase();  // ED4
       return s.toString();  
       // toString retorna uma representação da classe, nada melhor que a própria String para representar tal objeto de tal tipo
   }
Rodrigo_Sasaki

mapleplayer:
Foram criadas 5 Strings

public static String makinStrings() { String s = "Fred"; // Fred s = s + "47"; // Fred47 e 47 s = s.substring(2, 5); // ed4 s = s.toUpperCase(); // ED4 return s.toString(); // toString retorna uma representação da classe, nada melhor que a própria String para representar tal objeto de tal tipo }


Verdade hein… o toUpperCase retorna uma String nova sim.

giselezr

o teste deve estar com problema então…


mapleplayer

vou ser legal com vcs, tem uma lista de simulados no javaranch, alguns deles são free, basta se increver no site apenas
segue o link para a lista de simulados
https://www.coderanch.com/how-to/java/ScjpMockTests

eu particularmente não gostei do testkiller

pmlm

Este problema já foi discutido (penso que várias vezes até) aqui no forum

giselezr

depois de ler o link, penso que entendi…

public String makinStrings() {     
String s = "Fred";  // aqui não é criado uma string, é só atribuida da que ja esta no pool
s = s + "47";        // 1. Cria um objeto StringBuilder("Fred47")  
s = s.substring(2, 5); // 2. Cria a string "ed4"  
s = s.toUpperCase(); // 3. cria a string "ED4".  
return s.toString();    //  return this   
}

apesar de não ter lido em lugar nenhum a parte do (parte do outro link):

está fazendo o seguinte:
a) O Java, ao carregar a sua classe (ou seja, antes de executar o método “makinStrings”), vê que existe uma literal “Fred” no código, e então cria uma string “Fred” e a insere no pool de strings
b) Quando você executar o método “makinStrings”, você vai simplesmente atribuir à variável s uma referência para a string “Fred”, que já está criada e está no pool de strings.

Então, para efeitos dessa questão, esse comando não conta como criação de strings.

Agora já faz mais sentido…

Rodrigo_Sasaki

Como assim cria um StringBuilder? isso está documentado em algum lugar?

giselezr

dê uma olhada no link que o pmlm passou: http://www.guj.com.br/java/116352-duvida-na-quantidade-de-strings-criadas-resolvido

Rodrigo_Sasaki

Sim sim, eu li.

Até não sabia que ele carregava as Strings literais direto no pool de Strings, o que também me pareceu estranho.

O que eu quero saber é se existe alguma documentação que especifique esse comportamento.

giselezr

a parte do StringBuilder até é familiar, apesar de não ter encontrando a documentação, mas a parte que ele já cria as Strings no pool antes de passar pelo método e depois só recupera, achei muito esquisito…

E

O operador “+” é compilado de várias maneiras pelo Javac.

  1. Se ambos os operandos forem constantes strings, ele efetua a concatenação em tempo de compilação:
String s = "abc" + "def";

é compilado para algo semelhante a:

String s = __referência à string "abcdef" que está no pool de strings constantes___;
  1. Se você tiver uma sequência de vários operandos, todos strings, ele normalmente cria um StringBuilder no começo, e usa o método StringBuilder.toString() no fim:
String a = ...;
String b = ...;
String c = ...;
String s = a + b + c;

equivale a:

String s = new StringBuilder (a).append (b).append (c).toString();
  1. Se você tiver uma sequência de vários operandos, sendo que alguns deles são strings e outros não, ele normalmente cria um StringBuilder no começo, e usa o método StringBuilder.toString() no fim, e chama os overloads de StringBuilder.append que fazem conversão de dados:
String a = ...;
int b = ...;
Object c = ...;
String s = a + b + c;

equivale a:

String s = new StringBuilder (a).append (b).append (c).toString();
  1. Por que é que, mesmo o compilador criando uma StringBuilder o seguinte código abaixo é péssimo?
String[] t = "abc,def,ghi,asjk,sdlkd,fklklfkfk,jjajjaj";
String s = "";
for (String q : t.split(",")) {
     s = s + q; // você deve se lembrar que isso é compilado para "s = new StringBuilder(s).append(q).toString();"
}

É que para cada vez que você executa o loop, são criados 4 objetos:

  • Uma StringBuilder, que contém como valor inicial os caracteres de s. Essa StringBuilder contém um char[] que é uma cópia dos caracteres de s
  • Talvez seja realocado o char[] contido no StringBuilder se q for grande. Isso já dá o terceiro objeto
  • E depois toString() cria um quarto objeto, que é uma String.

Se você fizesse, em vez disso:

StringBuilder sb = new StringBuilder();
for (String q : t.split(",")) {
     sb.append (q); // isto deve no máximo criar um novo char[], não 4 objetos a cada iteração do loop. 
}
String s = sb.toString(); // só cria o String no final

iria economizar várias criações e cópias de objetos e arrays.
[/code]

Rodrigo_Sasaki

Entendi, é uma particularidade do javac então…

Sinceramente, eu não sabia que o javac utilizava Java pra compilar código Java hehehe.

Vivendo e aprendendo.

giselezr

e a parte do pool? é isso ali mesmo?

Rodrigo_Sasaki

entanglement, existe alguma maneira de eu ver isso acontecer? talvez descompilar o .class de alguma maneira.

Basicamente eu queria saber como você adquiriu essa informação.

wagnerfrancisco

É como você falou no post anterior. “Fred” e “47” já estavam no pool de literais. Como a pergunta é quantas strings são criadas quando o método é invocado, eles não contam (já estavam criados).

Rodrigo_Sasaki

Só pra quem ficou encucado que nem eu.

Eu fiz uns testes ontem pra ver como ver o StringBuilder, e vi que realmente é assim.

Descompilei o código do entanglement com o cavaj e recebi a seguinte saída:
public class Teste
{

    public Teste()
    {
    }

    public static void main(String args[])
    {
        String t = "abc,def,ghi,asjk,sdlkd,fklklfkfk,jjajjaj";
        String s = "";
        String args1[];
        int j = (args1 = t.split(",")).length;
        for(int i = 0; i < j; i++)
        {
            String q = args1[i];
            s = (new StringBuilder(String.valueOf(s))).append(q).toString();
        }

    }
}
Criado 19 de setembro de 2012
Ultima resposta 26 de set. de 2012
Respostas 26
Participantes 8