class TestClass <T extends SuperClass>{
public List<T> doSmth(){
///....
List testObjects = []
testObjects.add(new T(arg))
return testObjects;
}
}
class SuperClass{
}
class A extends SuperClass{
A(Arg arg){
....
}
class B extends SuperClass{
B(Arg arg){
....
}
////////test
class Main{
List <A> a
List <B> b
Main(){
this.a = new TestClass<A>().doSmth()
this.b = new TestClass<B>().doSmth()
}
}在行上发现异常(groovy.lang.GroovyRuntimeException:找不到匹配的SuperClass构造函数)
testObjects.add(new T(arg))这是非常正确的,因为SuperClass没有构造函数。但是子类有一个,并且所有的子类都有相同的签名,具有相同类型的arg。
有人能帮我找到解决问题的办法吗?
发布于 2016-04-02 19:01:55
代码不能工作的原因是A和B的构造函数不匹配。原因是缺少接受SuperClass中字符串的构造函数。
new T()并不像您期望的那样工作。在你的代码中,它变成了new SuperClass(arg)。下面的代码演示了这一点
class TestClass <T extends SuperClass> {
public void doSmth(){
println new T().class.simpleName;
}
}
class SuperClass{}
class A extends SuperClass{}
class B extends SuperClass{}
new TestClass<A>().doSmth()
new TestClass<B>().doSmth()
new TestClass<String>().doSmth() //even this works输出为
SuperClass
SuperClass
SuperClassTestClass <T>将打印Object。TestClass <T extends A>将打印A等。
Groovy在运行时没有泛型类型信息。Groovy甚至不做编译类型检查(例如new TestClass<String>())。但它保留了一些信息以使new T()工作。
Java的泛型实现包含一个称为“类型擦除”的特性,该特性在完成静态类型检查后“丢弃”泛型类型信息。这使得Java可以轻松地与遗留的“非泛型”库集成。Groovy目前做得更进一步,“在源代码级”抛弃了泛型信息。泛型信息保存在适当的签名内http://web.archive.org/web/20150102195947/http://groovy.codehaus.org/Generics
发布于 2016-04-02 18:10:18
不幸的是,无法使用new T创建泛型类型的新实例。所以你需要解决这个问题。
解决这个问题的一种方法是在doSmth()中包含一个闭包参数,用于为您创建实例。
public List<T> doSmth(Closure newT) {
List testObjects = []
testObjects.add(newT(arg))
return testObjects;
}并提供在调用该方法时创建新实例的代码:
Main() {
this.a = new TestClass<A>().doSmth { new A(it) }
this.b = new TestClass<B>().doSmth { new B(it) }
}https://stackoverflow.com/questions/36371166
复制相似问题