将Scala Any转换为Java对象

将Scala Any转换为Java对象,java,scala,reflection,scala-java-interop,Java,Scala,Reflection,Scala Java Interop,我在使用Scala的Java反射时遇到问题。我的代码: case class MyClass(id: String, value: Double) def create(values: Map[String, Any]): MyClass = { val constructor = classOf[MyClass].getConstructors.head val arguments = classOf[MyClass].getDeclaredFields().map(

我在使用Scala的Java反射时遇到问题。我的代码:

case class MyClass(id: String, value: Double)     

def create(values: Map[String, Any]): MyClass = {
   val constructor = classOf[MyClass].getConstructors.head
   val arguments = classOf[MyClass].getDeclaredFields().map( f => values(f.getName) )
   constructor.newInstance(arguments: _*).asInstanceOf[MyClass]
} 

create(Map("id" -> "CE0D23A", "value" -> 828.32))
我的问题是,我需要传递一个Map[String,Any],因为其中一个值是Double,但newInstance需要Object,而不是Any

我在scalas universe上也尝试过同样的方法:

case class MyClass(id: String, value: Double)     

def create(values: Map[String, Any]): MyClass = {
   val m = universe.runtimeMirror(getClass.getClassLoader)
   val myClass = universe.typeOf[MyClass].typeSymbol.asClass
   val cm = m.reflectClass(myClass)
   val ctro = universe.typeOf[MyClass].declaration(universe.nme.CONSTRUCTOR).asMethod
   val ctorm = cm.reflectConstructor(ctro)
   ctorm(values: _*).asInstanceOf[MyClass]
} 

create(Map("id" -> "CE0D23A", "value" -> 828.32))
这里的问题是,我只为示例介绍了MyClass。稍后,它应该是一个通用函数,如
defcreate(值:Map[String,Any]):T
。但我得到了以下例外:“T没有可用的TypeTag”

有没有办法转换这些值


谢谢

java.lang.Object
相当于Scala中的
AnyRef
,而不是
Any
。其思想是,Scala
Double
(大致相当于Java
Double
)是一个
Any
,而不是
AnyRef
java.lang.Double
是一个
AnyRef
,因此也是一个
Any

您只需将
Any
强制转换为
AnyRef
,即可执行必要的转换,将Scala
Double
转换为
java.lang.Double

scala> val x = 3.5
x: Double = 3.5

scala> x.getClass
res0: Class[Double] = double

scala> val y = x.asInstanceOf[AnyRef]
y: AnyRef = 3.5

scala> y.getClass
res1: Class[_ <: AnyRef] = class java.lang.Double
scala>valx=3.5
x:Double=3.5
scala>x.getClass
res0:Class[Double]=Double
scala>val y=x.asInstanceOf[AnyRef]
y:AnyRef=3.5
scala>y.getClass

好的,我迟到了一点,但我要说的是:

以下工作:

constructor.newInstance(arguments.asInstanceOf[Array[AnyRef]]: _*).asInstanceOf[MyClass]
另见:

建议:我会非常谨慎地使用反射。在Scala中,这是一种糟糕的风格。限制/封装反射的一种方法是:

case class MyClass(id: String, value: Double)     

object MyClass {

    import scala.util.Try
    def apply(map: Map[String, Any] /* this is asking for trouble */) : Option[MyClass]  =  for {
            id <- maybeT[String](map.get("id"))
            value <- maybeT[Double](map.get("value"))
        } yield MyClass(id, value)

    // a truly global utility?
    @inline def maybeT[T] ( a: Any /*Option[T]*/ ) : Option[T]= Try(a.asInstanceOf[Option[T]]).toOption.flatten //yep ugly as hell

}


MyClass(Map("id" -> "CE0D23A", "value" -> 828.32))
case类MyClass(id:String,value:Double)
对象MyClass{
导入scala.util.Try
def apply(map:map[String,Any]/*这是自找麻烦*/):Option[MyClass]=for{
(第828.32段)

我添加了第二个基于scalas universe的示例。也许你也知道这个问题的解决方案?或者没有办法将scalas universe运行时反射用于泛型?对不起,我不知道怎么做。也许你应该将其作为一个新的单独问题发布。