2016-04-04 101 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' –