我有一个Java类:
public class Parent
{
public int parentVal;
}
将有几个继承的Groovy类,如:
class Child1 extends Parent
{
def value1;
}
class Child2 extends Parent
{
def value2;
}
我希望Groovy中的一个集合仅限于包含Child1或Child2实例,因此如果集合包含Child1实例,则它不能包含Child2实例(或其他任何内容)。这是我的尝试:
import java.util.ArrayList;
public class MyCollection<T extends Parent>
{
private ArrayList<T> list = new ArrayList<T>();
public void setType(Class<T> cls)
{
this.cls = cls;
}
public void add(T item) throws Exception
{
if(item.getClass() == cls)
{
list.add(item);
}
else
{
throw new Exception("wrong argument type");
}
}
public T getItem(int index)
{
return list.get(index);
}
private Class<T> cls;
}
并在我的Groovy脚本中:
def c1 = new Child1()
c1.value1 = 1
c1.parentVal = 2;
def c2 = new Child2()
c2.value2 = 2
c2.parentVal = 3;
def myCol = new MyCollection()
myCol.setType(Child1.class)
myCol.add(c1)
myCol.add(c2) // throws an exception
最后一个语句确实抛出了“错误的参数类型”异常,但我是Java和Groovy的新手,所以我可能做错了。非常感谢任何建议。
答案 0 :(得分:3)
您采取的方式是抛出运行时错误。没错,它只是在编译时没有检查过。我不确定您是否可以使用Java的泛型,在同一声明中定义上限和下限。通过简单地使用<T extends Parent>
,它表示您可以使用Parent
延伸的任何内容,其中包括Child2
,而您只需要Child1
。我可以想到的另一种选择是在Parent上定义泛型,并在Child类中声明它,类本身就是泛型参数。然后它抛出编译器错误。另请注意@CompileStatic
或@TypeChecked
:
带有泛型声明的Parent
类:
class Parent<T> {
int parentVal
}
class Child1 extends Parent<Child1> {
def value1;
}
class Child2 extends Parent<Child2> {
def value2;
}
class MyCollection<T extends Parent<T>> {
def list = new ArrayList<T>()
void add(T item) throws Exception {
list.add(item);
}
T getItem(int index) {
return list.get(index);
}
}
和测试脚本。注意注释行不能编译:
//and in my Groovy script:
@groovy.transform.TypeChecked
def main() {
def c1 = new Child1()
c1.value1 = 1
c1.parentVal = 2;
def c2 = new Child2()
c2.value2 = 2
c2.parentVal = 3;
def myCol = new MyCollection<Child1>()
myCol.add(c1)
//myCol.add(c2) // doesn't compile
}
main()
答案 1 :(得分:1)