Scala:使用私有构造函数从泛型类型创建实例

时间:2016-10-19 10:26:48

标签: scala generics reflection

我有一个带有泛型类型参数的类,我想使用反射创建这种类型的实例。而且,该类型具有私有构造函数。 以下是问题的代码示例:

class X private (x: Int) {
}
class Y private (y: Int) {
}
abstract class Foo[T](z : Int) {
  var bar : T = createInstance[T](z)
  def createInstance[T](z: Int) : M = {
     ???
  }
}

这将允许我实例化Foo和访问栏:

class xFoo extends Foo[X]{
}

class yFoo extends Foo[Y]{
}

var xfoo = new xFoo(5)
println(xfoo.bar.x)

var yfoo = new yFoo(6)
println(yfoo.bar.y)

这应该打印出来' 5'和' 6'。

我尝试过以下方式使用隐式。

def createInstance[T](z: Int)(implicit tag: TypeTag[T]) : T = {
  val clazz = tag.tpe.getClass
  val ctor = class.getDeclaredConstructor(classOf[Int])
  ctor.setAccessible(true)
  return ctor.newInstance(z).asInstanceOf[T]
}

然而,我得到错误:

No TypeTag available for T

在行

var bar : T = createInstance[T](z)

有什么建议吗?谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

假设超类确实暴露了一些你正在寻找的方法/值:

class X private(val x: Int) {}

您可以像这样扩展它:

import scala.reflect._

class Foo[T](z : Int)(implicit ct: ClassTag[T]) {
  var bar : T = createInstance[T](z)
  def createInstance[T](z: Int) : T = {
    val ctor = ct.runtimeClass.getDeclaredConstructor(classOf[Int])
    ctor.setAccessible(true)
    ctor.newInstance(Int.box(4)).asInstanceOf[T]
  }
}

这使您可以致电:

class XFoo(n: Int) extends Foo[X](n)
println((new XFoo(5)).bar.x)