Attempting to generics-ify some legacy code, I'm stuck. I have a ParentObject which wraps a ChildObject to provide group-type operations on the ChildObject. Most usefully, it allows iteration over the collection of child objects. When I try to add some generics to the mix, I can't work out how to make it play friendly with the iterator method without either a "naming clash" error, or in the example below, a "The return type is incompatible with Iterable.iterator()" error. Any suggestions? (Bonus question - is there a better way to write the avoid thegetChildObjectByIndex() method to avoid type erasure complier warning other than suppressing the warnings?) Thanks a lot in advance for any help
public class ParentObject implements Iterable<ChildObject> {
protected List<? super ChildObject> theChildObjects;
@SuppressWarnings("unchecked")
public <T extends ChildObject> T getChildObjectByIndex(int idx) {
return (T)theChildObjects.get(idx);
}
publ开发者_C百科ic Iterator<? super ChildObject> iterator() {
return java.util.Collections.unmodifiableCollection(this.theChildObjects).iterator();
}
}
If ParentObject only contains one subtype of ChildObject, you could parametrize ParentObject on that type:
public class ParentObject<T extends ChildObject> implements Iterable<T> {
protected List<T> theChildObjects;
public T getChildObjectByIndex(int idx) {
return theChildObjects.get(idx);
}
public Iterator<T> iterator() {
return java.util.Collections.unmodifiableCollection(this.theChildObjects).iterator();
}
}
Seems like in your example ParentObject is some sort of container class that really has no relationship to ChildObject. Does ChildObject extend ParentObject? If so, that seems less than ideal. Also seems like you should be using "extends" in the generics instead of super, unless I'm just misunderstanding what you're trying to do. What about the following? Or is that too simple for what you want to do?
public class WidgetContainer<T> implements Iterable<T> {
protected List<T> theWidgets;
public T getWidgetByIndex(int idx) {
return theWidgets.get(idx);
}
public Iterator<T> iterator() {
return Collections.unmodifiableCollection(theWidgets).iterator();
}
}
WidgetContainer<SomeWidget> myWidgetContainer = new WidgetContainer<SomeWidget>();
Also I might cache a copy of the unmodifiable collection and use it each time you need an iterator instead of constructing one on the fly.
精彩评论