Stringの謎?

基本的なことで恥かしいんですけど、なんか納得できないんですよ。

class hensu{
	public static void main(String args[]){
		//Stringのテスト
		String a = "abc";
		String b = "abc";
		if(a==b){
			System.out.println("aとbは同一");
		}else{
			System.out.println("aとbは別");
		}
	}
}

これって、"abc"が格納されたStringオブジェクトを暗黙的に宣言し、その参照をaに代入してるんですよね?
で、bに対してもやはり暗黙的に宣言された上とは別のStringオブジェクトの参照を代入してると私は思ってるんですが、実際にはa==bがtrueなんですよ。

a==bがtrueだっつーことは、bに代入されているStringの"abc"はaに代入したものと同一のオブジェクト(同一の実体)ってことですよね?

で、bに代入するときには、aの時に暗黙宣言された"abc"のStringを使い回す、ということならそれでいいのですが、

class hensu{
	public static void main(String args[]){
		//Stringのテスト
		String a = "abc";
		String b = "abc";
		//追加
		a = a + "test";
		b = b + "test";
		if(a==b){
			System.out.println("aとbは同一");
		}else{
			System.out.println("aとbは別");
		}
	}
}

こうした場合、a==bがfalseになっちゃうんですよ。
これがなんでなのか、俺にわかるように説明しやがれお願いします。

ちなみに

class hensu{
	public static void main(String args[]){
		//Stringのテスト
		String a = "abc";
		a = a+"test";
		String b = "abctest";
		
		if(a==b){
			System.out.println("a=b");
		}else{
			System.out.println("a<>b");
		}
	}
}

これはa==bはfalseなんだよな・・・

まぁコレがわかんなくても困らないっていえば困らないんですけどね。
Stringでこんな比較しないだろうし・・・
でもなんかスッキリしないのってキモチ悪いじゃないですか。
そんなけで、先生方お願いします。