【问题标题】:Classcast exception on Scala map operation on List of Strings对字符串列表的 Scala 映射操作的 Classcastexception
【发布时间】:2019-06-21 02:41:50
【问题描述】:

我有一个类型安全的配置对象,其中包含地图数据类型。下面是conf文件中某个key的内容。

test_mapping = {
'15': [8000, 8002],
'5': [500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522],
....
}

这是我用来从配置中读取此密钥的代码。

scala> val test = config.getObject("test_mapping").asScala map { case (cat, et) => (cat -> et.unwrapped().asInstanceOf[java.util.ArrayList[String]].asScala.toList) }
test: scala.collection.mutable.Map[String,List[String]] = Map('15' -> List(8001, 8002), '5' -> List(500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522), '8' -> List(800, 801, 802, 803, 804), '2' -> List(200, 201, 202, 203, 204, 205...

在上面的代码中,我明白我做错了什么,conf 文件包含 Ints 列表,但我使用 asInstanceOf 强制转换为 List[String] 但它的工作原理如上所示。我不明白为什么地图值上的地图函数因 ClassCastException 而失败。请看下面的代码和错误。

scala> test.map( { case(c,e) => e.map(identity) } )
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
  at scala.collection.immutable.List.map(List.scala:286)
  at .$anonfun$res105$1(<console>:23)
  at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:237)
  at scala.collection.mutable.HashMap.$anonfun$foreach$1(HashMap.scala:149)
  at scala.collection.mutable.HashTable.foreachEntry(HashTable.scala:237)
  at scala.collection.mutable.HashTable.foreachEntry$(HashTable.scala:230)
  at scala.collection.mutable.HashMap.foreachEntry(HashMap.scala:44)
  at scala.collection.mutable.HashMap.foreach(HashMap.scala:149)
  at scala.collection.TraversableLike.map(TraversableLike.scala:237)
  at scala.collection.TraversableLike.map$(TraversableLike.scala:230)
  at scala.collection.AbstractTraversable.map(Traversable.scala:108)
  ... 28 elided

scala>

这与 List[_] 上的类型擦除有关吗?有人可以解释一下为什么转换为 List[String] 的第一行有效但遍历其元素失败?

谢谢!

【问题讨论】:

    标签: java scala classcastexception typesafe-config


    【解决方案1】:

    您对擦除的猜测是正确的。

    List[Integer]List[String] 在运行时具有完全相同的 JVM 类型。 这意味着演员阵容在运行时实际上并没有做任何事情。这是一个noop。 但是当您访问列表中的单个元素时,它们会作为字符串访问,因为在您转换之后,编译器“知道”这是一个 List[String]

    现在 JVM 实际验证了类型并且你得到了ClassCastException。 这不是 Scala 特有的,它在 Java(和其他类型化的 JVM 语言)中的工作方式相同。

    【讨论】:

      猜你喜欢
      • 2017-09-25
      • 1970-01-01
      • 2018-08-06
      • 2016-10-27
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多