Re: Generics and for each
- From: Lew <lew@xxxxxxxxxxxxx>
- Date: Fri, 7 Nov 2008 10:42:20 -0800 (PST)
Tom McGlynn wrote:
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.
That's not the reason. The issue occurs at compile time, therefore it
cannot be related to reifiability, which is a run-time issue.
You left out the type parameter on the 'implements Iterable' clause,
so the compiler has no way of matching the 'String' type of the loop
variable to the underlying type of the 'Iterable'.
Add a generic type parameter as indicated below. I used 'String' to
match your example, but it'd be better as '<T>'.
import java.util.ArrayList;
import java.util.Iterator;
public class Zz implements Iterable
<String> // got to nail down what *type* of Iterable it is
{
ArrayList<String> arr = new ArrayList<String>();
// consider using: List <String> arr = new ArrayList <String> ();
Zz() {
arr.add("a");
arr.add("b");
arr.add("c");
}
public Iterator <String> iterator() {
// Because you didn't implement 'Iterator <String>'
// the compiler cannot resolve your type in the 'main()' for-each
loop.
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.
Always but always cite the actual error message, character for
character, preferably by copy-and-paste, rather than paraphrasing.
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.
Nope. It's a compile-time issue, as you stated. Type erasure is a
run-time phenomenon, and you would not have discovered it via a
compile-time message.
Am I misunderstanding the idiom I need to do this,
Yes.
or do I still need to do the kinds of casts
Nope.
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.
Not if you neglect the type parameter in the 'implements' clause,
there isn't.
Even better than '<String>':
<sscce>
package eegee;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/** Zz illustrates how to implement <code>Iterable</code>.
* @param <T> generic type of iterator.
*/
public class Zz <T> implements Iterable <T>
{
List <T> arr = new ArrayList <T> ();
@Override
public Iterator <T> iterator()
{
return arr.iterator();
}
/** Add an element.
* @param val <code>T</code> element to add.
* @return boolean <code>true</code> iff the add succeeds.
*/
public boolean add( T val )
{
return arr.add( val );
}
/** Main method.
* @param args <code>String []</code> arguments.
*/
public static void main( String [] args )
{
Zz <String> z = new Zz <String> ();
z.add( "a" );
z.add( "b" );
z.add( "c" );
for ( String x : z )
{
System.out.println(x);
}
}
}
</sscce>
run:
a
b
c
BUILD SUCCESSFUL (total time: 1 second)
--
Lew
.
- Follow-Ups:
- Re: Generics and for each
- From: Tom McGlynn
- Re: Generics and for each
- References:
- Generics and for each
- From: Tom McGlynn
- Generics and for each
- Prev by Date: Re: Interview Questions
- Next by Date: Best graphing package for java?
- Previous by thread: Re: Generics and for each
- Next by thread: Re: Generics and for each
- Index(es):
Relevant Pages
|