Reputation: 2984
I've noticed something funny Java does (or at least Netbeans) when I use classes implementing ArrayList
and changing the generics type of the elements. I basically created an abstract class that extends ArrayList
and some subclasses that are supposed to work with String
objects (so something like ArrayList<String>
). One of the things I did to try to achieve that was this:
public abstract class A extends ArrayList {
...
}
@Override
public abstract class B extends A {
public Iterator<String> iterator() {
return super.iterator();
}
}
Another one was this:
public abstract class A extends ArrayList {
...
}
public abstract class B<String> extends A {
@Override
public Iterator<String> iterator() {
return super.iterator();
}
}
The first one overrides successfully the iterator()
method assigning a String value to it. The other one somehow cancels out the type casting. The funny thing is that none of them works when it comes to for loops. This receives type Object
instead of String
.
for (String s : B) {
...
}
Do you have any idea why this happens and how can I fix it without implementing my own iterator?
Upvotes: 1
Views: 2102
Reputation: 122439
OMG this is terrible:
public abstract class B<String> extends A {
@Override
public Iterator<String> iterator() {
return super.iterator();
}
}
String
is not the class String
, rather, you are declaring a new type variable called String
(like T
) that shadows the class String
Upvotes: 0
Reputation: 415
Use composition instead of Inheritance
public class A implements Iterable<String>{
List<String> myList = new ArrayList<String>();
//do operations on myList
public Iterator<String> iterator() {
return myList.iterator();
}
}
Upvotes: 1
Reputation: 115328
If you extend generic class you should care about generics. I mean that your declaration should look like
public abstract class A extends ArrayList<String> {
...
}
if you want to use strings or
public abstract class <T> A extends ArrayList<T> {
...
}
if you want your class to be generic.
In both cases you do not have to override iterator()
method: you can invoke its from super class and it will return you "good" iterator. Your declaration is equivalent to
public abstract class A extends ArrayList<Object> {
...
}
This is the reason for "strange" behavior.
BTW may I ask you why are you extending ArrayList
? It really sounds strange.
Upvotes: 0
Reputation: 14949
Not sure what you are trying to do but if I understand correctly you want a class that extends ArrayList and has a Generic type of String... Perhaps you are looking for this:
public abstract class A<T> extends ArrayList<T> {
...
}
public abstract class B extends A<String> {
...
}
Then in your code, this:
B myList = ...;
for ( String s : myList ) {
...
}
Will work just fine. Though I think you could come up with a much better solution. Do you have more specifics about your problem?
Upvotes: 4