String

13 respostas
ECO2004
public class Questao64 {

	public static void main(String[] args) {
	
		String x = null;
		
		if( x != x + 0 )
			System.out.println("Condição satisfeita");
	}
}

A dúvida: String x aponta para null. Na comparação, estou criando uma cópia do conteúdo de x e concatenando com 0. O novo String formado será “null0”. No if, será verificado se a String x possui uma referência para esse literal, correto? A comparação não é de valor, mas por referência, né?

Outra dúvida. Vamos considerar que x não seja null, mas qualquer outro valor. No pool de Strings, x apontaria para o seu respectivo valor. Na mesma comparação acima, seria verificado se a nova String formada é para quem x aponta no poll?

13 Respostas

ViniGodoy
É só testar:
public class Questao64 {

    public static void main(String[] args) {

        String x = null;

        if ("null0" == x + 0) {
            System.out.println("Condição satisfeita");
        }
    }
}
Concatenação gera uma nova String, mas isso funciona:
public class Questao64 {

    public static void main(String[] args) {

        String x = null;

        if ("null0".equals(x + 0)) {
            System.out.println("Condição satisfeita");
        }
    }
}
ViniGodoy
E isso imprime false:
public class Questao64 {

    public static void main(String[] args) {
        String x = null;
        System.out.println(x + 0 == x + 0);
    }
}
ViniGodoy
Outro código interessante:
Integer i = 128;
Integer j = 128;

System.out.println(i == 128);
System.out.println(i == j);

Depois faça a mesma coisa usando 127.

ECO2004
ViniGodoy:
E isso imprime false:
public class Questao64 {

    public static void main(String[] args) {
        String x = null;
        System.out.println(x + 0 == x + 0);
    }
}

Por que gera false? Porque estou comparando as referências de duas Strings?

ViniGodoy

Isso. Pelo mesmo motivo. Você criou duas strings diferentes com o texto “null0” e agora está comparando se são a mesma String.

Rodrigo_Sasaki

Quando você faz isso:public static void main(String[] args) { String x = null; if( x != x + 0 ) System.out.println("Condição satisfeita"); } O compilador gera isso: public static void main(String args[]){ String x = null; if(x != (new StringBuilder(String.valueOf(x))).append(0).toString()){ System.out.println("Condi\347\343o satisfeita"); } }E no exemplo do Vini, quando o código é assim:public static void main(String[] args) { String x = null; System.out.println(x + 0 == x + 0); }O código gerado pelo compilador é esse: public static void main(String args[]){ String x = null; System.out.println((new StringBuilder(String.valueOf(x))).append(0).toString() == (new StringBuilder(String.valueOf(x))).append(0).toString()); }Ficou mais fácil de entender as saídas agora?

Os exemplos foram descompilados com o Cavaj

yurifw
ViniGodoy:
Outro código interessante:
Integer i = 128;
Integer j = 128;

System.out.println(i == 128);
System.out.println(i == j);

Depois faça a mesma coisa usando 127.

a parte da string eu entendi, e se fosse seguir a mesma logica, o codigo q vc digitou era pra imprimir false na segunda linha, e imprime, mas pq qdo eu mudo os valores pra 127 ele imprime true? n saquei isso

ViniGodoy

Por que o Java tem um cache de números de -126 até 127. Então, se os números estiverem no mesmo intervalo, o mesmo objeto é retornado.

No caso do primeiro println, comparar um Integer com um int faz um AutoUnboxing. Por isso a comparação dá certo nos dois casos.

ViniGodoy

Por que o Java tem um cache de números de -126 até 127. Então, se os números estiverem no mesmo intervalo, o mesmo objeto é retornado.

No caso da primeira linha, comparar um Integer com um int faz um AutoUnboxing. Por isso a comparação dá certo nos dois casos.

yurifw

entendi, mto interessante isso ^^
maneiro mesmo, valeu pela explicação

ECO2004

Por que o Java tem um cache de números de -126 até 127. Então, se os números estiverem no mesmo intervalo, o mesmo objeto é retornado.

No caso do primeiro println, comparar um Integer com um int faz um AutoUnboxing. Por isso a comparação dá certo nos dois casos.

No caso de Integers, tanto faz quem faz auto-unboxing ou auto-boxing. Com o pool de Integers, se os valores que o int e o Integer possuírem forem iguais, retornará true.
Se forem diferentes, retornará false. Lógico que temos que verificar os limites desse pool, que é o intervalo de -128 a +127.

Vini, mas como você sabe quem está sofrendo a operação de boxing?

Nessa thread que abri há pouco http://www.guj.com.br/java/295928-auto-boxing-ou-auto-unboxing, eu criei um programa que mostra que sempre o segundo operando de uma comparação é quem sofre o boxing, auto-boxing ou auto-unboxing.

Queria a sua opinião!

Wilson

ViniGodoy

De onde você tirou que é sempre o último operando? O cavaj mostrou que as vezes é o primeiro, e as vezes é o segundo.

O que ele faz é o seguinte:
Atribuição:

  • Depende do tipo que recebe a atribuição. Se for objeto, faz Boxing, se for primitivo, faz Unboxing;
  • Comparações: Prioriza o unboxing;
  • Teste de ==: Faz unboxing, a menos que ambos os lados tenham um objeto. Nesse caso, compara referências.

A preferência tende a ser sempre para unboxing.

Se quiser ver as regras em detalhes:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

ECO2004

ViniGodoy:
De onde você tirou que é sempre o último operando? O cavaj mostrou que as vezes é o primeiro, e as vezes é o segundo.

O que ele faz é o seguinte:
Atribuição:

  • Depende do tipo que recebe a atribuição. Se for objeto, faz Boxing, se for primitivo, faz Unboxing;
  • Comparações: Prioriza o unboxing;
  • Teste de ==: Faz unboxing, a menos que ambos os lados tenham um objeto. Nesse caso, compara referências.

A preferência tende a ser sempre para unboxing.

Se quiser ver as regras em detalhes:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

Obrigado pelas dicas…já tinha corrigido no outro post.

Criado 19 de março de 2013
Ultima resposta 19 de mar. de 2013
Respostas 13
Participantes 4