java – 在Scala中传递类型作为参数

我想将类型传递给
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)
  }
点赞