Groovyの等価演算子について

Groovyの a==b は Javaのa.equals(b) ←オブジェクトの中身を見て同値か否かを判断
Groovyの a===bは Javaのa==b ←同じオブジェクトを比較しているか否かを判断
と、なるらしい、ほほぅ、なるほど。
というわけでサンプルを書いて確認


// StrCheck.groovy
a = "あいうえお"
b = a
c = "あいうえお"
d = 'かきくけこ'

println 'bとaは同じオブジェクトをさしている'
println 'aとcは別々のオブジェクトでたまたま中身が同じである'
println 'dはa,b,cどれとも異なる'

if(a === b){
println "a===b -> True # aとbは同じオブジェクトなのでこちらが正解"
}else{
println "a===b ->false # aとbは同じオブジェクトなのでこれはまずい"
}

if(a === c){
println "a===c -> True # aとcは異なるオブジェクトなのでこれはまずい"
}else{
println "a===c ->false # aとcは異なるオブジェクトなのでこちらが正解"
}

if(a == b){
println "a==b -> True # aとbが指しているオブジェクトの中身は同じなのでこちらが正解"
}else{
println "a==b -> false # aとbが指しているオブジェクトの中身は同じなのでこれはまずい"
}

if(a == c){
println "a==c -> True # aとcが指しているオブジェクトの中身は同じなのでこちらが正解"
}else{
println "a==c ->false # aとcが指しているオブジェクトの中身は同じなのでこれはまずい"
}

実行結果

groovy StrCheck.groovy
a===b -> True # aとbは同じオブジェクトなのでこちらが正解
a===c -> True # aとcは異なるオブジェクトなのでこれはまずい
a==b -> True # aとbが指しているオブジェクトの中身は同じなのでこちらが正解
a==c -> True # aとcが指しているオブジェクトの中身は同じなのでこちらが正解
あ?あれ?参照の比較ができてないじゃん
まぁ、文字列に関して言えば滅多に使わないし、意図的にそうしてるのかな?
JavaでもString型を==で比較して、原因不明のバグに悩まされる人とか、ありそうな話だし。
以下は同じコードをJavaで書いてみた

// StrCheck.java
public class StrCheck {

public static void main(String[] args){
String a;
String b;
String c;
String d;
String LF = "\n";

a = new String("あいうえお");
b = a;
c = new String("あいうえお");
d = new String("かきくけこ");


String statement = "aとbは同一オブジェクト" + LF +
"aとcは別々のオブジェクトで内容がたまたま同じ" + LF +
"dはa,b,cとは異なる";

System.out.println(statement);
statement = "==の動作確認";
System.out.println(statement);

if(a == b){
// 同じオブジェクトなのでこちらが入る
System.out.println("a == b -> True # aとbは同じオブジェクトなのでこちらが正解");
}else{
System.out.println("a == b ->false # aとbは同じオブジェクトなのでこれはまずい");
}

if(a == c){
System.out.println("a == c -> True # aとbは異なるオブジェクトなのでこれはまずい");
}else{
// aとcでは格納されているメモリ位置が別(異なるオブジェクトである)
System.out.println("a == c ->false # aとbは異なるオブジェクトなのでこちらが正解");
}

if(a == d){
System.out.println("a == d is true # aとdは別物だからこれは論外");
}else{
// "あいうえお"と"かきくけこ"が異なるからfalseではない。
// aとdでは格納されるメモリ位置が別だから(異なるオブジェクトである)
System.out.println("a == d is false # aとdは別物だからこちらで正解");
}

statement = "equalsメソッドの動作確認";
System.out.println(statement);

if(a.equals(b)){
// "あいうえお"と"あいうえお"を比較するのでこちら
System.out.println("a.equals(b) -> true # aとbが指しているオブジェクトの中身は同じなのでこちらが正解");
}else{
System.out.println("a.equals(b) ->false # aとbが指しているオブジェクトの中身は同じなのでこれはまずい");
}

if(a.equals(c)){
// "あいうえお"と"あいうえお"を比較するのでこちら
System.out.println("a.equals(c) -> true # aとcが指しているオブジェクトの中身は同じなのでこちらが正解");
}else{
System.out.println("a.equals(c) ->false # aとcが指しているオブジェクトの中身は同じなのでこれはまずい");
}

if(a.equals(d)){
System.out.println("a.equals(d) is true");
}else{
// "あいうえお"と"かきくけこ"が異なるからfalse
System.out.println("a.equals(d) is false");
}

}
}

実行結果

aとbは同一オブジェクト
aとcは別々のオブジェクトで内容がたまたま同じ
dはa,b,cとは異なる
==の動作確認
a == b -> True # aとbは同じオブジェクトなのでこちらが正解
a == c ->false # aとbは異なるオブジェクトなのでこちらが正解
a == d is false # aとdは別物だからこちらで正解
equalsメソッドの動作確認
a.equals(b) -> true # aとbが指しているオブジェクトの中身は同じなのでこちらが正解
a.equals(c) -> true # aとcが指しているオブジェクトの中身は同じなのでこちらが正解
a.equals(d) is false
まぁ、これは当然なんだがJavaは長いなぁ、ほとんどがお約束文なのに。。