T
Tom McGlynn
Recently I've been trying to implement Iterable in some of my classes
to take advantage of the for-each syntax, e.g., to loop over the
results in a query. It doesn't work quite as nicely as I would like
due -- I think -- to non-reifiability of generics. Here's an example
that illustrates
the problem.
import java.util.ArrayList;
import java.util.Iterator;
public class Zz implements Iterable {
ArrayList<String> arr = new ArrayList<String>();
Zz() {
arr.add("a");
arr.add("b");
arr.add("c");
}
public Iterator<String> iterator() {
return arr.iterator();
}
public static void main(String[] args) {
Zz z = new Zz();
for (String x: z) {
System.out.println(x);
}
}
}
This fails with an incompatible types message when compiling the for
loop.
If I replace 'String x' with 'Object x' all is copacetic, but as it
stands it fails because it doesn't know that the Iterator is a
<String> iterator. I gather that's information lost due to type
erasure.
Am I misunderstanding the idiom I need to do this, or do I still need
to do the kinds of casts
that generics were supposed to help me get rid of. I.e., is there any
operational advantage of specifying
public Iterator<X> iterator()
versus
public Iterator iterator()
when X is a real class not a generic type. [Presumably it's still a
good thing to do for documentation.]
I've no doubt this has come up before -- if you can point to some
earlier discussion or documentation I'd appreciate it.
Regards,
Tom McGlynn
to take advantage of the for-each syntax, e.g., to loop over the
results in a query. It doesn't work quite as nicely as I would like
due -- I think -- to non-reifiability of generics. Here's an example
that illustrates
the problem.
import java.util.ArrayList;
import java.util.Iterator;
public class Zz implements Iterable {
ArrayList<String> arr = new ArrayList<String>();
Zz() {
arr.add("a");
arr.add("b");
arr.add("c");
}
public Iterator<String> iterator() {
return arr.iterator();
}
public static void main(String[] args) {
Zz z = new Zz();
for (String x: z) {
System.out.println(x);
}
}
}
This fails with an incompatible types message when compiling the for
loop.
If I replace 'String x' with 'Object x' all is copacetic, but as it
stands it fails because it doesn't know that the Iterator is a
<String> iterator. I gather that's information lost due to type
erasure.
Am I misunderstanding the idiom I need to do this, or do I still need
to do the kinds of casts
that generics were supposed to help me get rid of. I.e., is there any
operational advantage of specifying
public Iterator<X> iterator()
versus
public Iterator iterator()
when X is a real class not a generic type. [Presumably it's still a
good thing to do for documentation.]
I've no doubt this has come up before -- if you can point to some
earlier discussion or documentation I'd appreciate it.
Regards,
Tom McGlynn