Java で "1" == "1" が true になる理由

Java で String(文字列)の比較をする場合、「==」じゃなくて、equals メソッドを使えと言われます。それは、「==」が同一性の比較であって同値性の比較では無いからなんですが、
ここで、下のコードの実行結果ってどうなると思います?

System.out.println("1" == "1");
System.out.println("1" == String.valueOf(1));
System.out.println("1".equals("1"));
System.out.println("1".equals(String.valueOf(1)));


答えは、true, false, true, true なんですよね。


ここで、"1" == "1" が true になる理由って何なんですかね?
何となく、Groovy での実行結果も貼っとく。


ちなみに、.NET(C#)の場合、リテラル文字列はインターンプールとして、参照を保持してその参照を見にいくからっていうので説明出来るんですが、Java の場合はどうなんでしょう?
.NET 実行結果(久々のCSharpConsole)


※インターンプールについての資料を MSDN から見つけられなかった。どこにあるか知ってる方おられたら教えて下さい。