在Java中,
==
和equals()
是一个混乱之源,而Groovy加剧了这种混乱。Groovy将==
操作符映射到了Java中的equals()
方法。假如我们想比较引用是否相等(也就是原始的==
的语义),该怎么办呢?必须使用Groovy中的is()
。下面通过一个例子来理解其区别。
GroovyForJavaEyes/Equals.groovy
str1 = 'hello'
str2 = str1
str3 = new String('hello')
str4 = 'Hello'
println "str1 == str2: ${str1 == str2}"
println "str1 == str3: ${str1 == str3}"
println "str1 == str4: ${str1 == str4}"
println "str1.is(str2): ${str1.is(str2)}"
println "str1.is(str3): ${str1.is(str3)}"
println "str1.is(str4): ${str1.is(str4)}"
来看一下Groovy中==
操作符的行为以及使用is()
方法的结果:
str1 == str2: true
str1 == str3: true
str1 == str4: false
str1.is(str2): true
str1.is(str3): false
str1.is(str4): false
观察发现,Groovy的==
映射到equals()
,这个结论并不总是成立,当且仅当该类没有实现Comparable
接口时,才会这样映射。如果实现了Comparable
接口,则==
会被映射到该类的compareTo()
方法。
下面例子说明了这种行为。
GroovyForJavaEyes/WhatsEquals.groovy
class A {
boolean equals(other) {
println "equals called"
false
}
}
class B implements Comparable {
boolean equals(other) {
println "equals called"
false
}
int compareTo(other) {
println "compareTo called"
0
}
}
new A() == new A()
new B() == new B()
下面的输出显示,Comparable
的优先级高:
equals called
compareTo called
通过输出可以看到,在实现了Comparable
接口的类上,==
操作符选择了compareTo()
,而不是equals()
。
注意 在比较对象时,请首先问一下自己,要比较的是引用还是值。然后再问一下,是不是使用了正确的操作符。