在groovy中动态重写'equals'和'hashCode'

在groovy中动态重写'equals'和'hashCode',groovy,overriding,equals,hashcode,Groovy,Overriding,Equals,Hashcode,如果我动态重写类的equals和hashCode方法,则调用这些方法直接调用重写版本,但将它们用于set将使用非重写版本。为什么会这样?对于所有用途,是否仍然可以动态覆盖这两种方法 class SuperClass { public boolean equals(Object other) { println 'non overridden equals called' false } public int hashCode() { println 'non

如果我动态重写类的
equals
hashCode
方法,则调用这些方法直接调用重写版本,但将它们用于set将使用非重写版本。为什么会这样?对于所有用途,是否仍然可以动态覆盖这两种方法

class SuperClass {
  public boolean equals(Object other) {
    println 'non overridden equals called'
    false
  }

  public int hashCode() {
    println 'non overridden hashCode called'
    1
  }
}

SuperClass.metaClass.equals = { Object other ->
  println 'overridden equals called'
  true
}

SuperClass.metaClass.hashCode = { ->
  println 'overridden hashCode called'
  1
}

def a = new SuperClass()
def b = new SuperClass()

println a.hashCode() // overriden hashCode called
println b.hashCode() // overriden hashCode called
println a.equals(b) // overriden equals called

println([a, b].toSet().size()) // non overriden methods called, returns 2 instead of 1
列表上调用
toSet()

由于这是通过调用程序进行的,因此调用程序知道
元类
,并且应该给您一个包含一个元素的集合


实际上,我会避免通过元类更改
hashCode
方法。正如您所看到的,很难确切地知道何时会处理它,处理得好的地方可能不会期望hashCode时刻发生变化。

您在哪里覆盖了
Set
的equals()和hashCode()在元类中?为什么我需要重写
Set
equals
hashcode
?对不起,我读了一半的问题:-)所以groovy无法重写方法,所以Java类会看到更改?Java类不知道
元类,所以Java代码不会看到更改(除非它是通过使用Groovy调用程序或检查元类本身来寻找它)在动态重写toString()方法时也存在类似的问题。
    Set<T> answer = new HashSet<T>(self.size());
    answer.addAll(self);
    return answer;
println( [a, b].unique().toSet().size() )