Autoboxing - igualdade

porque são diferentes as duas condições abaixo:

String nome1= new String("Fulano");
String nome2 = new String("Fulano");
		
if(nome1 == nome2){ //FALSE
    System.out.println("Iguais");			
}
String nome1= "Fulano";
String nome2 = "Fulano";
		
if(nome1 == nome2){ //TRUE 
    System.out.println("Iguais");			
}

Na primeira se cria um endereço na memória pelo que eu entendi e o segundo com o autoboxing não?

Obrigado por qualquer ajuda

Autoboxing é a criação ou referência a um objeto wrapper para um tipo primitivo, e String não é um tipo primitivo.

Não se usa “==” para se comparar objetos.
Se você criou duas instancias de objetos do tipo String e realiza o “==” ela não vai comparar o conteúdo da String mas sim suas referências, que são distintas.

A idéia é essa mesmo comparar “==” para ver como se comporta… respondendo os dois… não existe um tipo primitivo para String. String seria um char[]? Como foi dito aqui:

Depois, se esse eh o motivo, String no fundo no fundo eh soh um wrapper com alguns metodos a mais em cima de um char[] aqui: http://www.guj.com.br/java/42600-classe-string

E não entendi ainda porque:

[code]
String nome1= “Fulano”;
String nome2 = “Fulano”;

	if(nome1 == nome2){
	    System.out.println("Iguais");			
	}[/code]

Retorna igual… se não tem um tipo primitivo…

link legal para ver:
http://www.davidflanagan.com/2004/02/equality-and-autoboxing.html

Dá uma lida aqui:

http://download.oracle.com/javase/6/docs/api/java/lang/String.html#intern()

[quote=rogeriopaguilar]Dá uma lida aqui:

http://download.oracle.com/javase/6/docs/api/java/lang/String.html#intern()
[/quote]

Obrigado pela dica… aqui retorna true:

String nome3= new String("Fulano");
		String nome4 = new String("Fulano");
				
		if(nome3.intern() == nome4.intern()){
		    System.out.println("Iguais 2");			
		}

Se não me engano a diferença é que quando você atribui assim:

String nome = "fulano" String nome2 = "fulano"

O compilador vai criar um simbolo apenas para “fulano”, que é uma String e apontar as duas referencias pra ela, dai o ‘==’ funciona.

String nome = new String("fulano") String nome2 = new String("fulano")

Quando você instancia uma String passando outra String no construtor ela copia o conteúdo do parâmetro mas gera um nova String, daí o ‘==’ não será o bastante.

Me fiz entender?

Um abraço.

[quote=daveiga]Se não me engano a diferença é que quando você atribui assim:

String nome = "fulano" String nome2 = "fulano"

O compilador vai criar um simbolo apenas para “fulano”, que é uma String e apontar as duas referencias pra ela, dai o ‘==’ funciona.

String nome = new String("fulano") String nome2 = new String("fulano")

Quando você instancia uma String passando outra String no construtor ela copia o conteúdo do parâmetro mas gera um nova String, daí o ‘==’ não será o bastante.

Me fiz entender?

Um abraço.
[/quote]

Só não entendi o “simbolo” seria o mesmo endereço de memória é isso?

outro link interessante:
http://www.javacamp.org/javaI/primitiveTypes.html

É isso ae, o “símbolo” é o mesmo endereço de memória. Como o valor é uma literal o compilador coloca a string numa espécie de “pool”, como está descrito no javadoc. É uma espécie de otimização que o compilador faz e com isso há economia de memória. Quando você cria a instância “na mão”, sem ser um valor literal, este mecanismo não é utilizado, a menos que você chame o método intern, como fez no exemplo.

Até mais.

rogeriopaguilar era isso mesmo que eu queria dizer.

De toda forma nunca use ‘==’ para Strings.

[quote=dtxk]porque são diferentes as duas condições abaixo:

String nome1= new String("Fulano");
String nome2 = new String("Fulano");
		
if(nome1 == nome2){ //FALSE
    System.out.println("Iguais");			
}
String nome1= "Fulano";
String nome2 = "Fulano";
		
if(nome1 == nome2){ //TRUE 
    System.out.println("Iguais");			
}

Na primeira se cria um endereço na memória pelo que eu entendi e o segundo com o autoboxing não?

Obrigado por qualquer ajuda[/quote]

aqui temos envolvida nessa pergunta dois conceitos, vamos por partes:

primeiro o conceito de igualdade, o == não compara se os dois objetos são vamos dizer assim equivalentes, se seu conteúdo deve ser considerado igual, isso compara se as suas duas variáveis apontam para o mesmo objeto la na memória (lembre-se que variáveis de objetos são apenas um “apontador” para o objeto, não são o objeto em si, mas sim a “flexinha”, um terceiro conceito alias).

o segundo conceito é a forma pela qual a JVM lida com strings, quando você cria uma string no seu código abrindo aspas digitando algo e fechando aspas, a JVM cria essa string e a insere em um pool interno de objetos de string dela. ok, se você criar outro objeto de string da mesma forma, abrindo e fechando aspas, com o mesmo conteudo, a jvm deve identificar que ja existe um objeto assim no pool dela e então usará esse objeto já criado, não um novo, então o == retornará true, ja que se referem ao mesmo objeto aproveitado la no pool. Diferentemente quando você usar o operador new com algum objeto (seja qual for, incluindo string) ai a jvm criará um objeto novo e irá inseri-lo na memória, por ser um objeto novo, diferente, então o == retornará false.

ainda em tempo, para se comparar a igualdade entre objetos, deve-se usar o método equals, se você comparar usando o equals ao invés do == no seu exemplo você terá o resultado que você espera. Caso seja uma classe sua, que você criou, que não seja da api e você queira fazer comparações você precisará sobrescrever o método equals (crie um método equals na sua classe).

em tempo, o conceito de auto boxing que eu saiba se refere a conversão implícita de tipos primitivos para objetos, não é o caso deste exemplo.