加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

使用Scala和Jackson以及java.lang.Integer或scala.Int对泛型类型

发布时间:2020-12-16 18:50:06 所属栏目:安全 来源:网络整理
导读:我们都知道泛型类型在 Java和Scala下受类型擦除的影响.但是我们使用Jackson和Scala Jackson Module在Scala中遇到了一个奇怪的问题. 我创建了一个小测试来显示问题. import com.fasterxml.jackson.databind.ObjectMapperimport com.fasterxml.jackson.module.
我们都知道泛型类型在 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)
  }
}

以上的输出是:

Test 1: 6
Test 2: java.lang.String cannot be cast to java.lang.Integer
Test 3: 6
Test 4: 6

这种不同的行为来自哪里? Generic Type Erasure,Jackson,Jackson Scala Module?

解决方法

这成为一个常见的问题,我为它写了一个 FAQ:

[A]ll primitive type parameters are represented as Object to the JVM. … The Scala module has informed Jackson that Option is effectively a container type,but it relies on Java reflection to determine the contained type,and comes up with Object.

The current workaround for this use case is to add the @JsonDeserialize annotation to the member being targeted. Specifically,this annotation has a set of parameters that can be used for different situations:

  • contentAs for collections or map values (supported)
  • keyAs for Map keys (currently unsupported)

Examples of how to use this annotation 07001.

好奇的常见问题解答中有更多细节.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读