Scala传递类类型作为参数
问题描述:
嘿,我试图在scala中以最好的方式编写下面的代码,如果有更好的方法,请帮助我!Scala传递类类型作为参数
public final <T> T deserialize(String jsonString, Class<T> klass) {
try {
return objectMapper.readValue(jsonString, klass);
} catch (Exception e) {
LOG.error("Failed to deserialize {} to class {}, {}", jsonString, klass, e);
}
return null;
}
低于一个好的?
def deserialize[T: Manifest](value: String): T = {
mapper.readValue(value, typeReference[T])
}
答
如果您需要获得Class[T]
,使用scala.reflect.ClassTag
(不TypeTag
,你可以从它那里得到的Class
,但只在一个迂回的方式):
def deserialize[T](value: String)(implicit tag: ClassTag[T]): T = {
mapper.readValue(value, tag.runtimeClass.asInstanceOf[Class[T]])
}
小心在调用时不要忘记类型参数(即deserialize[String]("\"a\"")
,而不是deserialize("\"a\"")
),否则Scala会将其推断为Nothing
。
也有可能你需要通过盒装类而不是基元(例如deserialize[java.lang.Integer]("1")
),如果是的话你可以解决这个问题,但这将需要额外的代码。
答
使用TypeTag
而不是Manifest
。清单已弃用。在代码中,为了获得通用参数的类型信息,您可以使用typeTag[T]
。我改变了反序列化的实现为了演示typeTag如何工作以及如何访问泛型类型信息。
def deserialize[T: TypeTag](value: T) = println(typeTag[T].tpe)
上述功能打印类型信息。您可以使用typeTag[T]
上定义的其他方法来执行更复杂的逻辑。
斯卡拉REPL
scala> def deserialize[T: TypeTag](value: T) = println(typeTag[T].tpe)
deserialize: [T](value: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])Unit
scala> deserialize(List(1, 2, 3))
List[Int]
scala> deserialize(1)
Int
scala> deserialize("hello")
String
'Manifest'已弃用。使用'TypeTag' – Falmarri