5

这就是我得到的:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModuleobject 

AppStart extends App {
  val mapper = new ObjectMapper()
  mapper.registerModule(DefaultScalaModule)

  val json = """{"id":"AB","stuff":"whatever"}"""
  val obj = mapper.readValue(json, classOf[TestClass])

  println(obj.id.get) // prints AB !!!
}

case class TestClass(id: Option[Int] = None, stuff: Option[String] = None)

同时,这甚至没有建立:

val bad: Option[Int] = "AB"

这里显然有问题。我在项目中使用的版本:

scalaVersion := "2.11.6"

libraryDependencies += "com.fasterxml.jackson.module" % "jackson-module-scala_2.11" % "2.7.3"

4

2 回答 2

3

不,这不会破坏JVM类型安全。JVM 不支持泛型,就其类型而言idis Option, not Option[Int]。为了打破类型安全,你必须得到一个TestClasswho idis not an Option

反射和强制转换肯定会破坏 Java 和 Scala 的类型安全,而且它们应该这样做。

要在 Jackson 中正确反序列化泛型,您需要提供其他信息(请参阅http://wiki.fasterxml.com/JacksonFAQ#Deserializing_Generic_types),并且 jackson-module-scala 允许 Scala 编译器提供它:

您还可以混合 ScalaObjectMapper(实验性)来获得丰富的包装器,这些包装器会自动将 scala 清单直接转换为 TypeReferences 以供 Jackson 使用:

val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val myMap = mapper.readValue[Map[String,Tuple2[Int,Int]]](src)

我不知道它是否会自动阻止您遇到的问题。

于 2016-05-17T06:56:25.700 回答
-1

您需要查看 Scala 生成的类的字节码。

我的猜测是反射仍在工作,但是该字段的运行时类型不是它在 Scala 中出现的类型,因此 JVM 不会阻止这种情况的发生。

于 2016-05-17T06:13:07.843 回答