我想将类型传递给
Scala中的函数.
问题详细
第一次迭代
我有以下Java类(来自外部源):
public class MyComplexType {
public String name;
public int number;
}
和
public class MyGeneric<T> {
public String myName;
public T myValue;
}
在这个例子中,我希望MyComplexType是MyGeneric的实际类型;在真正的问题中有几种可能性.
我想使用Scala代码反序列化JSON字符串,如下所示:
import org.codehaus.jackson.map.ObjectMapper
object GenericExample {
def main(args: Array[String]) {
val jsonString = "{\"myName\":\"myNumber\",\"myValue\":{\"name\":\"fifteen\",\"number\":\"15\"}}"
val objectMapper = new ObjectMapper()
val myGeneric: MyGeneric[MyComplexType] = objectMapper.readValue(jsonString, classOf[MyGeneric[MyComplexType]])
val myComplexType: MyComplexType = myGeneric.myValue
}
}
它编译好,但发生运行时错误:
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to MyComplexType
at GenericExample$.main(GenericExample.scala:9)
第二次迭代
解决问题的工作方案:
val jsonString = "{\"myName\":\"myNumber\",\"myValue\":{\"name\":\"fifteen\",\"number\":\"15\"}}"
val objectMapper = new ObjectMapper()
val myGeneric: MyGeneric[MyComplexType] = objectMapper.readValue(jsonString, classOf[MyGeneric[MyComplexType]])
myGeneric.myValue = objectMapper.readValue(objectMapper.readTree(jsonString).get("myValue").toString, classOf[MyComplexType])
val myComplexType: MyComplexType = myGeneric.myValue
不好但是很有效. (如果有人知道如何让它变得更好,那也会受到欢迎.)
第三次迭代
第二次迭代解决方案中的行多次出现在实际问题中,因此我想创建一个函数.更改变量是JSON格式的字符串和MyComplexType.
我想要这样的东西:
def main(args: Array[String]) {
val jsonString = "{\"myName\":\"myNumber\",\"myValue\":{\"name\":\"fifteen\",\"number\":\"15\"}}"
val myGeneric = extractMyGeneric[MyComplexType](jsonString)
val myComplexType: MyComplexType = myGeneric.myValue
}
private def extractMyGeneric[T](jsonString: String) = {
val objectMapper = new ObjectMapper()
val myGeneric = objectMapper.readValue(jsonString, classOf[MyGeneric[T]])
myGeneric.myValue = objectMapper.readValue(objectMapper.readTree(jsonString).get("myValue").toString, classOf[T])
myGeneric
}
这不起作用(编译器错误).我已经玩过Class,ClassTag,classOf的各种组合,但它们都没有帮助.还有编译器和运行时错误.你知道如何传递以及如何在Scala中使用这种类型吗?谢谢!
最佳答案 当您使用jackson解析json时,可以使用
TypeReference来解析泛型类型.例:
val jsonString = "{\"myName\":\"myNumber\",\"myValue\":{\"name\":\"fifteen\",\"number\":\"15\"}}"
val objectMapper = new ObjectMapper()
val reference = new TypeReference[MyGeneric[MyComplexType]]() {}
val value: MyGeneric[MyComplexType] = objectMapper.readValue(jsonString, reference)
如果您仍想使用Jackson,我认为您可以使用TypeReference类型创建参数.喜欢:
implicit val typeReference = new TypeReference[MyGeneric[MyComplexType]] {}
val value = foo(jsonString)
println(value.myValue.name)
def foo[T](jsonStr: String)(implicit typeReference: TypeReference[MyGeneric[T]]): MyGeneric[T] = {
val objectMapper = new ObjectMapper()
objectMapper.readValue(jsonStr, typeReference)
}