Scala 如何以反射方式创建新集合?

Scala 如何以反射方式创建新集合?,scala,scala-collections,Scala,Scala Collections,我有一个集合的实例,我希望将其存储在外部,然后还原回原始集合类型。比如说 class Foo { var x : List[Int] } val f = new Foo f.x = List(1, 2, 3) 我“序列化”了f,我想反射地创建一个新的Foo,f2,并用正确的结果填充f2.x 我可以通过执行[Foo].newInstance的classOf[Foo].newInstance来创建新的Foo,但是如何创建正确的集合类型并填充它呢 注意,我在这里做了很多假设,值得注意的是: 1

我有一个集合的实例,我希望将其存储在外部,然后还原回原始集合类型。比如说

class Foo {
  var x : List[Int]
}

val f = new Foo
f.x = List(1, 2, 3)
我“序列化”了f,我想反射地创建一个新的Foo,f2,并用正确的结果填充f2.x

我可以通过执行[Foo].newInstance的
classOf[Foo].newInstance来创建新的Foo,但是如何创建正确的集合类型并填充它呢

注意,我在这里做了很多假设,值得注意的是: 1) 我知道f.x的类型,我甚至可以序列化它的类型 2) 我将x的内容序列化为保留值的内容 3) 我不想使用任何“标准”序列化

我曾尝试使用原始集合中可用的构建器,但我不太明白它是如何工作的,足以实现它的

谢谢


Dave

如果我们对您试图解决的问题有更好的了解,例如,为什么您不想使用标准对象序列化,那么在这里提供帮助会更容易

也就是说,如果您确实想对Scala集合类进行反射,您可能需要了解Scala当前如何编译其类和对象:

  • 如果希望列表对象使用类(而不是列表类),则名称为
    scala.collection.immutable.List$
    ——请注意最后的美元符号

  • 如果您想要单例列表对象实例,它将存储为字段
    MODULE$

  • 大多数scala collection companion对象都提供了一个
    newBuilder
    方法,该方法创建的对象具有一个
    +=
    $plus$eq
    )方法和一个
    结果
    方法,允许您创建一个新的集合

所以你可以这样做:

scala> def buildByReflection[T](collectionClassName: String, items: Array[T]) = {
     |   val companionClass = Class.forName(collectionClassName + "$")
     |   val companion = companionClass.getField("MODULE$").get(null)
     |   val newBuilder = companionClass.getMethod("newBuilder")
     |   val builder = newBuilder.invoke(companion)
     |   val plusEq = builder.getClass.getMethod("$plus$eq", classOf[Object])
     |   for (item <- items) {
     |     plusEq.invoke(builder, item.asInstanceOf[AnyRef])
     |   }
     |   builder.getClass.getMethod("result").invoke(builder)
     | }
buildByReflection: [T](collectionClassName: String,items: Array[T])java.lang.Object

scala> buildByReflection("scala.collection.immutable.List", Array(1, 2, 3))
res0: java.lang.Object = List(1, 2, 3)
scala>defbuildbyreflection[T](collectionClassName:String,items:Array[T])={
|val companionClass=Class.forName(collectionClassName+“$”)
|val companion=companionClass.getField(“模块$”).get(null)
|val newBuilder=companionClass.getMethod(“newBuilder”)
|val builder=newBuilder.invoke(伴随)
|val plusEq=builder.getClass.getMethod(“$plus$eq”,classOf[Object])
|对于(项buildByReflection(“scala.collection.immutable.List”,数组(1,2,3))
res0:java.lang.Object=List(1,2,3)

Foo
的代码没有编译…如果你想要一个具体的类,你不应该遗漏任何抽象成员。好吧,这不是重点。假设上面的行是:var x:List[Int]=null