Dúvida de conceito JAVA: Referência de objeto em memória

Galera, boa tarde!!!

Estou com uma pequena dúvida de conceito, que no momento não está atrapalhando meu trabalho, mas me deixou com uma pulga atrás da orelha…rs

olhem esse código de exemplo:

public class Main {

	public static void main(String[] args) {
		run();
	}
	
	public static void run () {
		
		VO vo = new VO();
		String teste;
		
		teste = "variavel: Tentando concatenar...";
		System.out.println(teste);
		concatenar(teste);
		System.out.println(teste);

		System.out.println("");

		vo.teste = "vo: Tentando concatenar...";
		System.out.println(vo.teste);
		concatenar(vo);
		System.out.println(vo.teste);
		
	}
	
	public static void concatenar(String a) {
		a += " consegui!!!";
	}

	public static void concatenar(VO vo) {
		vo.teste += " consegui!!!";
	}	

}

class VO {
	String teste;
}

Esse código resulta no seguinte resultado:

variavel: Tentando concatenar...
variavel: Tentando concatenar...

vo: Tentando concatenar...
vo: Tentando concatenar... consegui!!!

A idéia é tentar criar um método que não utilize return, e sim execute as alterações necessárias na String apenas pela referência do objeto em memória. Quando chamo o método concatenar(VO vo), ele passa para o método a instância do objeto VO criada na classe Main, então quando concateno a String, estou executando isso na variável que está dentro da instância da classe VO criada no Main.
Porém quando faço isso utilizando o método concatenar(String a), isso não acontece da mesma forma. Aparentemente o que está acontecendo é uma substituição do objeto String teste criado na Main por outro objeto String criado no método.
É isso mesmo que está acontecendo?
Alguém sabe exatamente o conceito que explica isso?
E como resolver?

Valeu!!!

O primeiro conceito de String em java é String’s são inalteraveis, não há nenhuma situação onde você consegue alterar um objeto String…

Qualquer forma que aparentemente modifica um objeto String, na realidade está criando um novo, o +, concat(), toUpperCase(), toLowerCase(), replace(), replaceAll(), todos criam um novo objeto…

Faça o seguinte teste:

[code]String str1 = "teste";
String str2 = str1;

if(str1==str2){
System.out.println("Mesmo objeto!");
}else{
System.out.println("Objetos distintos!");
}

str1 += "abc";

if(str1==str2){
System.out.println("Mesmo objeto!");
}else{
System.out.println("Objetos distintos!");
}[/code]

[quote=“Documentação”]The String class represents character strings. All string literals in Java programs, such as “abc”, are implemented as instances of this class.

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.[/quote]