在混合 Java/Scala 环境中,我有一个参数化类,它需要其类型参数才能正确覆盖 equals 和 hashCode。感谢这个博客,我编写了这个方法来检查是否是这种情况,使用 ClassTag:
class SomeClass[KeyType, ValueType] (arg1: Converter[KeyType], arg2:Converter[ValueType]) {
// concrete values of KeyType/ValueType not available at construction time
enforceEqualsHashImpl
// enforceEqualsHashImpl[KeyType, ValueType] : "error: No ClassTag available for KeyType "
def enforceEqualsHashImpl[KeyType : ClassTag, ValueType : ClassTag]= {
def checkEqualsEqualsHash[T](c:Class[T]): Boolean = {
def checkequals[T](c:Class[T]):Class[_] ={
val equalsDeclaringClass = c.getMethod( "equals", classOf[Object]).getDeclaringClass();
if ( classOf[Object].equals( equalsDeclaringClass ) )
throw new Exception( "HazelIndex7 parametrized by key class" + c + " which does not override equals")
equalsDeclaringClass
}
def checkHash[T](c:Class[T]):Class[_] ={
val hashCodeDeclaringClass = c.getMethod( "hashCode").getDeclaringClass();
if ( classOf[Object].equals( hashCodeDeclaringClass ) )
throw new Exception( "HazelIndex7 parametrized by key class" + c + " which does not override hashCode")
hashCodeDeclaringClass
}
val equalsDeclaringClass = checkequals(c)
val hashDeclaringClass = checkHash(c)
val equals = equalsDeclaringClass.equals(hashDeclaringClass)
if (!equals)
throw new Exception("Equals in class " + c + " is implemented by "+ equalsDeclaringClass + " but hashCode is implemented by: " + hashDeclaringClass );
equals
}
checkEqualsEqualsHash(classTag[KeyType].runtimeClass)
checkEqualsEqualsHash(classTag[ValueType].runtimeClass)
}
但是,我得到了这个例外:
java.lang.NoSuchMethodException: scala.runtime.Nothing$.equals(scala.runtime.Nothing$)
at java.lang.Class.getMethod(Class.java:1624)
在我看来,由于某种原因,ClassTag.runtimeClass 无法解析类型参数?这段代码有问题吗?什么可能导致此异常?
还尝试过这样的事情:
enforceEqualsHashImpl[KeyType, ValueType](classTag[KeyType], classTag[ValueType])
def enforceEqualsHashImpl[KeyType , ValueType ](implicit kc:ClassTag[KeyType],vc:ClassTag[ValueType])= ...
这导致:
error: No ClassTag available for KeyType
enforceEqualsHashImpl[KeyType, ValueType](classTag[KeyType], classTag[ValueType])
error: No ClassTag available for ValueType ....
可能相关:请注意,类型参数必须由构造函数参数 (arg1/arg2) 间接推断,这些参数不是类型参数的具体值。
有没有更好的方法来检查equals/hashCode?