【问题标题】:Ensure that Groovy ArrayList objects are of the same class确保 Groovy ArrayList 对象属于同一类
【发布时间】:2014-02-13 18:57:56
【问题描述】:

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

【问题讨论】:

    标签: java arraylist groovy


    【解决方案1】:

    您的做法是引发运行时错误。这没有错,只是在编译时没有检查。我不确定您是否可以使用 Java 的泛型在同一个声明中定义上限和下限。通过简单地使用&lt;T extends Parent&gt;,它表示您可以使用任何扩展Parent,包括Child2,而您只需要Child1。我能想到的另一种选择是在父类上定义一个泛型,并在子类中声明它,类本身就是泛型参数。然后它会引发编译器错误。另请注意需要@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()
    

    【讨论】:

    • 谢谢两位的回答
    【解决方案2】:

    因为 groovy 支持泛型

    http://groovy.codehaus.org/Generics

    您可能可以声明一个ArrayList&lt;Child1&gt;,而 groovy 会为您解决问题。

    【讨论】:

    • 如果我在 groovy 中声明和 ArrayList 似乎该事件接受 Child2 实例或事件整数
    • 试试@CompileStatic@TypeChecked
    猜你喜欢
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    相关资源
    最近更新 更多