我想用以下类实例化一个新对象:
class Test[T : ClassTag](val value : T) extends Serializable
private object Test {
private var testClass : Class[_] = _
def setTestClass(test : Class[_]) : Unit = {
testClass = test
}
def apply[T : ClassTag](value : T) : Test[T] = {
testClass.getConstructors()(0).newInstance(value).asInstanceOf[Test[T]]
}
}
class Subtest[T : ClassTag](
override val value : T,
val additional : Integer
) extends Test[T](value)
我在某处设置了setTestClass
的测试类,该字符串已从字符串加载Class.forName
。我们说它是"Subtest"
。我想实例化一个新的Subtest[String]
- 例如以下代码:
Test("my random string") // It should return a new Subtest[String]
问题是newInstance
抛出java.lang.IllegalArgumentException: wrong number of arguments
。我已经检查了parameterTypes
的{{1}},并且有两种参数类型:
好。如何提供ClassTag?这里有什么问题? 有没有更好的方法,解决方法呢?
答案 0 :(得分:3)
T: ClassTag
语法称为上下文绑定。它是类型为ClassTag[T]
的隐式参数的语法糖。换句话说,以下类签名是等效的:
class Test[T : ClassTag](val value : T)
class Test[T](val value: T)(implicit val ev: ClassTag[T])
所以你要找的构造函数需要另一个参数。使用上下文绑定语法时,您始终可以使用implicitly
来获取所需的参数(由于上下文绑定的语义,因此保证存在该参数)。或者,当您知道classTag
运算符可用时,可以使用ClassTag[T]
运算符直接获取AnyRef
的实例。
另一个细节是,在像这样的对象中使用类型参数时,它需要是apply
。
因此,您的def apply[T <: AnyRef : ClassTag](value : T) : Test[T] = {
testClass.getConstructors.head.newInstance(value, classTag[T]).asInstanceOf[Test[T]]
}
方法可能如下所示:
app.directive("dir", function(){
return {
restrict:"AE",
scope: {},
controller: function(){},
templateUrl: "templates/testpostlink.html",
compile: function(){
return {
pre: function(){
},
post:function(scope, EL, attrs){
// Here I am wondering how to get that div (let say scope.show is true)
}
};
}// end of compile
};
});