lon*_*uro 6 java generics json scala jackson
我们都知道泛型类型在Java和Scala下受类型擦除的影响.但是我们使用Jackson和Scala Jackson Module在Scala中遇到了一个奇怪的问题.
我创建了一个小测试来显示问题.
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
object GenericTest {
case class TestWithInt(id: Option[Int])
case class TestWithInteger(id: Option[Integer])
def main(args: Array[String]) {
val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)
// Test with scala's Int
val test = mapper.readValue[TestWithInt]("""{ "id" : 5 }""", classOf[TestWithInt])
print("Test 1: ")
println(test.id.get + 1)
val test2 = mapper.readValue[TestWithInt]("""{ "id" : "5" }""", classOf[TestWithInt])
print("Test 2: ")
try {
println(test2.id.get + 1)
} catch {
case e: ClassCastException => println(e.getMessage)
}
// Test with java.lang.Integer
val test3 = mapper.readValue[TestWithInteger]("""{ "id" : 5 }""", classOf[TestWithInteger])
print("Test 3: ")
println(test3.id.get + 1)
val test4 = mapper.readValue[TestWithInteger]("""{ "id" : "5" }""", classOf[TestWithInteger])
print("Test 4: ")
println(test4.id.get + 1)
}
}
Run Code Online (Sandbox Code Playgroud)
以上的输出是:
Test 1: 6
Test 2: java.lang.String cannot be cast to java.lang.Integer
Test 3: 6
Test 4: 6
Run Code Online (Sandbox Code Playgroud)
这种不同的行为来自哪里?Generic Type Erasure,Jackson,Jackson Scala Module?
这正成为一个如此普遍的问题,我为此写了一个常见问题解答:
[A]ll 原始类型参数表示为
ObjectJVM。... Scala 模块已通知 Jackson 实际上Option是一种容器类型,但它依赖于 Java 反射来确定所包含的类型,并提出Object.此用例的当前解决方法是将
@JsonDeserialize注释添加到目标成员。具体来说,这个注解有一组可以用于不同情况的参数:
contentAs用于集合或映射值(支持)keyAs用于映射键(当前不受支持)可以在测试目录中找到如何使用此注释的示例。
对于好奇的人来说,常见问题解答中有更多详细信息。
| 归档时间: |
|
| 查看次数: |
1788 次 |
| 最近记录: |