设置迭代器的Java泛型

时间:2011-11-07 16:57:50

标签: java generics for-loop iterator

当我使用实现ArrayList的类并更改元素的泛型类型时,我注意到有趣的Java(或至少是Netbeans)。我基本上创建了一个扩展ArrayList的抽象类和一些应该与String对象一起使用的子类(类似于ArrayList<String>)。我努力实现的目标之一是:

public abstract class A extends ArrayList {
   ...
}
@Override
public abstract class B extends A {
   public Iterator<String> iterator() {
      return super.iterator();
   }
}

另一个是:

public abstract class A extends ArrayList {
   ...
}
public abstract class B<String> extends A {
   @Override
   public Iterator<String> iterator() {
      return super.iterator();
   }
}

第一个成功覆盖iterator()方法,为其分配String值。另一个以某种方式取消了类型转换。有趣的是,当涉及到循环时,它们都不起作用。这会收到Object类型,而不是String

for (String s : B) {
   ...
}

你知道为什么会发生这种情况吗?如何在不实现我自己的迭代器的情况下修复它?

4 个答案:

答案 0 :(得分:4)

不确定你要做什么,但如果我理解正确你想要一个扩展ArrayList的类并且有一个Generic类型的String ...也许你正在寻找这个:

public abstract class A<T> extends ArrayList<T> {
    ...
}
public abstract class B extends A<String> {
    ...
}

然后在你的代码中,这个:

B myList = ...;
for ( String s : myList ) {
    ...
} 

工作得很好。虽然我认为你可以提出一个更好的解决方案。你有关于你的问题的更多细节吗?

答案 1 :(得分:1)

使用合成而不是继承

    public class A implements Iterable<String>{
        List<String> myList = new ArrayList<String>();
        //do operations on myList
        public Iterator<String> iterator() {
             return myList.iterator();
        }
    }

答案 2 :(得分:0)

如果你扩展泛型类,你应该关心泛型。我的意思是你的声明应该是

public abstract class A extends ArrayList<String> {
   ...
}

如果你想使用字符串或

public abstract class <T> A extends ArrayList<T> {
   ...
}

如果你希望你的班级是通用的。

在这两种情况下,您不必重写iterator()方法:您可以从超类调用它,它将返回“好”迭代器。您的声明等同于

public abstract class A extends ArrayList<Object> {
   ...
}

这就是“奇怪”行为的原因。

我可以问你为什么要延长ArrayList?这听起来很奇怪。

答案 3 :(得分:0)

OMG这太糟糕了:

public abstract class B<String> extends A {
   @Override
   public Iterator<String> iterator() {
      return super.iterator();
   }
}

String不是类String,而是声明一个名为String的新类型变量(如T),它隐藏了类String