将Java Object(实际上是一个Scala Map)转换为Scala Map



有一个编译时的任务,我需要使用反射运行(打扰调用者和被调用者是Scala源文件),但我得到一个运行时错误:

java.lang.ClassCastException: 
scala.collection.immutable.Map$Map2 cannot be cast 
to scala.collection.immutable.Map
反射类:

object jsRoutes {
  def getRoutesMap: Map[String,String] = {...}
}

调用代码:(loader是Scala 2.10.2类加载器)

val appLoader = new java.net.URLClassLoader(path, loader)
val clazz = appLoader.loadClass("controllers.jsRoutes")
val routesMap = clazz.getMethod("getRoutesMap")

任何将java.lang.Object强制转换为预期返回类型Map[String,String]的尝试都会导致上面的ClassCastException

routesMap.invoke(new Object).asInstanceOf[Map[String,String]]...

或不匹配:

routesMap.invoke(new Object) match {
  case x: Map[String,String] => ...
  case _ => println("not matched")
}

从来没有听说过Map$Map2,在目标类中它是Map[String,String],所以不确定反射调用时的返回类型是什么。

可以打印未转换的java.lang.Object (Map)内容。

谢谢你的提示,这是令人沮丧的;-)

您可能正在尝试跨类加载器强制转换。您不能这样做——每个类装入器维护自己的层次结构(对于那些没有传递给公共父装入器的类)。尝试在返回的映射和新创建的映射上调用getClassLoader

顺便说一下,Map$Map2只是一个实现细节——Map的一个子类,用于处理双元素映射。它的强制类型转换正常:

scala> val m = Map(1->"one", 2 -> "two"): Object
m: Object = Map(1 -> one, 2 -> two)
scala> m.getClass
res0: Class[_ <: Object] = class scala.collection.immutable.Map$Map2
scala> m.asInstanceOf[scala.collection.immutable.Map[Int,String]]
res1: scala.collection.immutable.Map[Int,String] = Map(1 -> one, 2 -> two)

相关内容

  • 没有找到相关文章

最新更新