我只是通过使用 Jackson JSON 反序列化破坏了 JAVA 类型安全吗?
Did I just break JVM type safety by using Jackson JSON deserialisation?
这是我得到的:
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"
您需要查看 class Scala 生成的字节码。
我的猜测是反射仍然有效,但是该字段的运行时类型不是它在 Scala 中出现的类型,因此 JVM 不会阻止这种情况的发生。
不,这不会破坏 JVM 类型安全。 JVM 不支持泛型,就其而言id
的类型是Option
,而不是Option[Int]
。要破坏类型安全,你必须得到一个 TestClass
其 id
不是 Option
.
反射和转换肯定会破坏 Java 和 Scala 的类型安全,而且它们应该会。
要在 Jackson 中正确反序列化泛型,您需要提供额外信息(参见 http://wiki.fasterxml.com/JacksonFAQ#Deserializing_Generic_types)并且 jackson-module-scala 允许 Scala 编译器提供它:
You can also mixin ScalaObjectMapper (experimental) to get rich wrappers that automatically convert scala manifests directly into TypeReferences for Jackson to use:
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val myMap = mapper.readValue[Map[String,Tuple2[Int,Int]]](src)
我不知道它是否会自动阻止您遇到的问题。
这是我得到的:
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"
您需要查看 class Scala 生成的字节码。
我的猜测是反射仍然有效,但是该字段的运行时类型不是它在 Scala 中出现的类型,因此 JVM 不会阻止这种情况的发生。
不,这不会破坏 JVM 类型安全。 JVM 不支持泛型,就其而言id
的类型是Option
,而不是Option[Int]
。要破坏类型安全,你必须得到一个 TestClass
其 id
不是 Option
.
反射和转换肯定会破坏 Java 和 Scala 的类型安全,而且它们应该会。
要在 Jackson 中正确反序列化泛型,您需要提供额外信息(参见 http://wiki.fasterxml.com/JacksonFAQ#Deserializing_Generic_types)并且 jackson-module-scala 允许 Scala 编译器提供它:
You can also mixin ScalaObjectMapper (experimental) to get rich wrappers that automatically convert scala manifests directly into TypeReferences for Jackson to use:
val mapper = new ObjectMapper() with ScalaObjectMapper mapper.registerModule(DefaultScalaModule) val myMap = mapper.readValue[Map[String,Tuple2[Int,Int]]](src)
我不知道它是否会自动阻止您遇到的问题。