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をチェックするためのより良い方法はありますか?