确保Groovy ArrayList对象属于同一个类

时间:2014-02-13 18:57:56

标签: java arraylist groovy

我有一个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的新手,所以我可能做错了。非常感谢任何建议。

2 个答案:

答案 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)

因为groovy支持泛型

http://groovy.codehaus.org/Generics

您可能会声明ArrayList<Child1>并且groovy会为您解决问题。