我有这个代码在我的项目中反复出现,我们为每个类型的序列化到Avro
class FooKryoRegistrator extends KryoRegistrator {
override def registerClasses(kryo: Kryo) {
kryo.register(classOf[Foo], SpecificRecordBinarySerializer(classTag[Foo]))
kryo.register(classOf[GenericData.Array[_]], new SpecificInstanceCollectionSerializer(classOf[java.util.ArrayList[_]]))
}
}
现在我不想在我的项目中为每个实体(Foo,Bar,Baz .....)编写这个Registrator类,而是认为将这个更通用。所以我做了
class GenericKryoRegistrator[T] extends KryoRegistrator {
override def registerClasses(kryo: Kryo) {
kryo.register(classOf[T], SpecificRecordBinarySerializer(classTag[T]))
kryo.register(classOf[GenericData.Array[_]], new SpecificInstanceCollectionSerializer(classOf[java.util.ArrayList[_]]))
}
}
但是我收到编译时错误
class type required but T found
我搜索了这个错误并发现了一个建议,我应该使用ClassTag而不是class。所以我将实现改为
class GenericKryoRegistrator[T] extends KryoRegistrator {
override def registerClasses(kryo: Kryo) {
kryo.register(classTag[T].runtimeClass, SpecificRecordBinarySerializer(classTag[T]))
kryo.register(classOf[GenericData.Array[_]], new SpecificInstanceCollectionSerializer(classOf[java.util.ArrayList[_]]))
}
}
但现在说
No ClassTag available for T
答案 0 :(得分:2)
如果将类标记作为类的隐式参数,则可以使用它:
class GenericKryoRegistrator[T] (implicit ct: ClassTag[T]) extends KryoRegistrator {
override def registerClasses(kryo: Kryo) {
kryo.register(ct.runtimeClass, SpecificRecordBinarySerializer(ct))
kryo.register(classOf[GenericData.Array[_]], new SpecificInstanceCollectionSerializer(classOf[java.util.ArrayList[_]]))
}
}