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