JDK-6185386 : Iterable must return an Iterator of ? extends T
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2004-10-27
  • Updated: 2010-04-02
  • Resolved: 2004-10-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0Resolved
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
foreach loop (for :) requires an array or an Iterable objet.

The method iterator() of Iterable has a return type
typed Iterator<T> but this type is too restrictive and could be
relaxed to Iterator<? extends T>.

foreach loop only reads information from the Iterator<T>
so it could use an iterator typed Iterator<? extends T>.
Furthermore, Iterator has no method that takes a
T as argument so Iterator<T> is too restrictive because
it doesn't permit the use of subtypes of T.

Because Iterator<? extends T> is a subtype of
Iterator<T>, the proposed change is straighforward.

Note perhaps the same idea could be applyed to
Collection class.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile the code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
it compile without compiler error
ACTUAL -
the program doesn't compile

ERROR MESSAGES/STACK TRACES THAT OCCUR :
incompatible types
found   : java.util.Iterator<capture of ? extends T>
required: java.util.Iterator<T>

return c1.iterator();

Chooser.java line 22	27 octobre 2004 15:34:08


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Chooser<T> implements Iterable<T> {

  public Chooser(Collection<? extends T> c1,
                Collection<? extends T> c2) {
    this.c1=c1;
    this.c2=c2;
  }
  
  public Iterator<T> iterator() {
    if (c1.size()<c2.size())
      return c1.iterator();
    else
      return c2.iterator();
  }
  
  private final Collection<? extends T> c1;
  private final Collection<? extends T> c2;
  
  public static void main(String[] args) {
    ArrayList<String> l1=new ArrayList<String>();
    Collections.addAll(l1,args);
    
    ArrayList<Integer> l2=new ArrayList<Integer>();
    l2.add(3);
    
    for(Comparable<?> c:new Chooser<Comparable<?>>(l1,l2))
      System.out.println(c);
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
the workaround is funny, create a Iterator<T> that wraps
the Iterator<? extends T>.

public Iterator<T> iterator() {
    final Iterator<? extends T> it;
    if (c1.size()<c2.size())
      it=c1.iterator();
    else
      it=c2.iterator();
    
    return new Iterator<T>() {
      public boolean hasNext() {
        return it.hasNext();
      }
      public T next() {
        return it.next();
      }
      public void remove() {
        it.remove();
      }
    };
  }
###@###.### 10/27/04 19:13 GMT