2016-04-04 49 views
0

我有这样的代码,一遍又一遍地出现在我的项目为每个类型的类,我们序列化的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[_]])) 
    } 
} 

现在,而不必写这Registrator类为每个实体(富,Bar,Baz .....)在我的项目中,我认为这会更好。所以,我没有

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 

我GOOGLE了这个错误,我发现我应该使用,而不是类ClassTag的建议。所以我改变了实施

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 

回答

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[_]])) 
    } 
} 
+0

谢谢。那么调用者将如何实例化这个类呢?我们将如何获得隐式的实际参数? –

+0

我不确定这些机制,但我相信编译器会自动'提供'classtag' –