【问题标题】:Generics: Why the implemented collections returns an object instead of the specified type?泛型:为什么实现的集合返回一个对象而不是指定的类型?
【发布时间】:2013-12-04 02:51:13
【问题描述】:

我正在尝试使用自定义 MapEntries 实现 OrderedMapEntry 列表 - 因为我需要使用 Vectors 的自定义解决方案,所以我不能使用 TreeMap(http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html)。我实现了一个没有任何错误的自定义列表,但是当我在增强的 for 循环中使用 OrderedMapEntries 类时,它返回一个 Object

  • 使用增强的 for 循环时如何确保类型安全?我的实现在确保这种类型安全方面做错了什么?

    public class OrderedMapEntries<K, V> implements Iterator, Iterable{
    
        private Vector<MapEntry<K, Vector<V>>> vector;
        private int vectorIndex;  // initializes with -1
    
        class MapEntry<A, B extends AbstractList<V>> implements Iterator, Iterable{
            // MapEntry implementation
    
        public void insert(int index, K key, Vector<V> vec){
            MapEntry<K, Vector<V>> mapEntry = new MapEntry<>(key, vec);
            vector.add(index, mapEntry);
        }
    
        @Override
        public MapEntry<K, Vector<V>> next(){
            vectorIndex++;
            return vector[vectorIndex]; 
        }
    }
    

我尝试使用增强的 for 循环来迭代集合,但它失败了,因为 next() 返回一个 Object 而不是我指定的元素。

OrderedMapEntries<Integer, String> ome = new OrderedMapEntries<>();
// I filled it with some test data

for (OrderedMapEntries<Integer, String>.MapEntry<Integer, Vector<String>> entry : ome){
    ; 
    }

【问题讨论】:

  • 请至少发布一个可编译的类。甚至没有声明类型参数K
  • 谢谢!当我为帖子简化它时,我监督了 K 的问题。

标签: java generics


【解决方案1】:

您正在实现Iterable,一个原始类型,而不是Iterable&lt;K&gt;Iterable&lt;V&gt;。如果像这样省略类型参数,那么iterator的签名就变成-

Iterator iterator();

它返回一个Iterator,而不是Iterator&lt;K&gt;Iterator&lt;V&gt;,其next 方法将具有如下签名 -

Object next();

这就是您在增强的 for 循环中获得 Object 的原因,因为它在内部调用 Iteratornext 来获得下一个元素。

如果您使用这样的原始类型,您几乎永远无法确保正确的类型安全。如需更多信息,请查看Effective Java,第 23 条 - 不要在新代码中使用原始类型

另外,你的OrderedMapEntries 类应该只实现Iterable&lt;E&gt;(请查看ArrayList 是如何做到的)。在其中实现 iterator 方法,以便将适当的 Iterator&lt;E&gt; 返回到增强的 for 循环。

【讨论】:

    【解决方案2】:

    您正在实现IteratorIterable 的原始类型。首先,您应该永远不要同时实现它们。其次,如果您想实现其中之一,请实现泛型类型而不是原始类型。这是一个显示How to implement iterable 的示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 1970-01-01
      • 2011-02-02
      相关资源
      最近更新 更多