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具有相同的类型。
有人可以帮我找到解决问题的方法吗?
答案 0 :(得分:3)
不幸的是,无法使用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) }
}
答案 1 :(得分:2)
您的代码无法正常工作的原因与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
SuperClass
TestClass <T>
将打印Object
。 TestClass <T extends A>
将打印A
,依此类推。
Groovy在运行时没有泛型类型信息。 Groovy甚至不进行编译类型检查(例如new TestClass<String>()
)。但它保留了一些信息以使new T()
起作用。
Java的泛型实现包含一个称为&#34;类型擦除的功能&#34; &#34;扔掉&#34;完成静态类型检查后的泛型类型信息。这使得Java可以轻松地与遗留的&#34;非泛型&#34;库。 Groovy目前做得更进一步,抛弃了泛源信息&#34;在源级&#34;。泛型信息保存在签名中http://web.archive.org/web/20150102195947/http://groovy.codehaus.org/Generics