首页 > 解决方案 > 为什么当 String.valueOf() 进行强制转换时 toString 不起作用

问题描述

我需要将 Json 解析为 Map[String,String] 结构。Json 可能包含数字和字符串类型作为值。

所以为了将它存储为字符串,我应用了 toString 方法,它抛出了 ClassCastException。但是,如果应用 String.valueOf() 一切正常。

  1. 为什么这样?
  2. 如果有更好的方法来做这种铸造?
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule

import scala.collection.Map
import scala.util.parsing.json.JSON

val mapper = new ObjectMapper()
mapper.registerModule(DefaultScalaModule)


val str = "[ { \"name\": \"VehicleType\", \"value\": 11 }, { \"name\": \"VehicleWeight\", \"value\": \"12000\" } ]"
val customfields = JSON.parseFull(str) match {
  case Some(map: List[Map[String, String]]) =>
    // map.map(map => {map("name") -> map("value").toString}).toMap

    // that throws:
    // java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.String
    //  at #worksheet#.$anonfun$customfields$1.apply(scratch.scala2:14)
    //  at #worksheet#.$anonfun$customfields$1.apply(scratch.scala2:14)
    //  at scala.collection.immutable.List.map(scratch.scala2:269)
    //  at #worksheet#.customfields$lzycompute(scratch.scala2:14)

    // that works fine 
    map.map(map => {map("name") -> String.valueOf(map("value"))}).toMap
  case _ => Map.empty[String, String]
}

标签: javascalacastingautoboxing

解决方案


因为模式匹配匹配 List 类型,但不会一直匹配到 map 内的所有类型,这就是您输入Some子句的原因。

所以,而不是 case Some(map: List[Map[String, String]]) =>

尝试这样做:

case Some(map: List[Map[String, _]]) =>
     map.map(map => {map("name") -> 
     map("value") match {
     case s: String => s
     case i: java.lang.Number => i
     case unexpectedType => throw Exception(s"Unexpected type $unexpectedType")
   }.toString}).toMap

这样您就可以安全地处理地图中的每个值。


推荐阅读