Reputation: 3076
I will post my question at the bottom.
Below is the class that other classes extend from.
public class people {
class family extends people {
}
class friends extends people {
}
class coworkers extends people {
}
}
Below is the class that has the method getAllPeopleByClass that gets invoked by the getMembers() method in the selection classes:
public class processing {
static processing process = null;
private Collection<family> familyList = new ArrayList<family>();
private Collection<coworkers> cowList = new ArrayList<coworkers>();
private Collection<friends> friendList = new ArrayList<friends>();
public processing(){
}
public static processing getInstance() {
if (process == null)
process = new processing();
return process;
}
public <T> Collection<people> getAllPeopleByClass(Class<T> clazz) {
Collection<people> peopleCollection;
peopleCollection.addAll(getList(clazz));
return peopleCollection;
}
private <T> Collection<? extends people> getList(Class<T> clazz) {
if (clazz == family.class) {
return familyList;
} else if (clazz == coworkers.class) {
return cowList;
} else { // else if clazz == friends.class
return friendList;
}
}
And finally, the classes that use processing:
public class familySelection {
public Collection<family> getMembers() {
Collection<family> f;
f = processing.getInstance().getAllPeopleByClass(family.class); //type mismatch
return f;
}
}
public class coworkerSelection {
public Collection<coworkers> getMembers() {
Collection<coworkers> c;
c = processing.getInstance().getAllPeopleByClass(coworkers.class); //type mismatch
return c;
}
}
public class friendsSelection {
public Collection<friends> getMembers() {
Collection<friends> f;
f = processing.getInstance().getAllPeopleByClass(friends.class); //type mismatch
return f;
}
}
My problem is that I get type mismatch from the getAllPeopleByClass call in each of my getMembers() methods.
I have tried this:
public class familySelection {
public Collection<family> getMembers() {
Collection<? extends people> f; //changed to extend from people
f = processing.getInstance().getAllPeopleByClass(family.class);
return (Collection<family>) f; //cast warning - dont want that
}
}
This works, but I get a cast warning, which I don't want and I don't want to suppress it. This is the closest I have come to fixing the problem. Also, the return type of getMembers() must remain as is. Does anyone have a way to do this without any warnings? Or even somehow handle this generically? Thanks!
Upvotes: 1
Views: 138
Reputation: 736
I would choose this version. It also require warning suppression but I think this is better place to do that.
I also allowed myself to change your Singleton implementation. If you really want to do it consider using enum.
public enum processing {
INSTANCE;
private Collection<family> familyList = new ArrayList<family>();
private Collection<coworkers> cowList = new ArrayList<coworkers>();
private Collection<friends> friendList = new ArrayList<friends>();
public static processing getInstance() {
return INSTANCE;
}
public <T extends people> Collection<T> getAllPeopleByClass(Class<T> clazz) {
Collection<T> peopleCollection = new ArrayList<T>();
peopleCollection.addAll(getList(clazz));
return peopleCollection;
}
@SuppressWarnings("unchecked")
private <T extends people> Collection<T> getList(Class<T> clazz) {
if (clazz == family.class) {
return (Collection<T>) familyList;
} else if (clazz == coworkers.class) {
return (Collection<T>) cowList;
} else { // else if clazz == friends.class
return (Collection<T>) friendList;
}
}
}
And familySelection:
public class familySelection {
public Collection<family> getMembers() {
Collection<family> f = processing.getInstance().getAllPeopleByClass(family.class);
return f;
}
}
Upvotes: 0
Reputation: 7212
Use the super
keyword:
public class familySelection {
public Collection<? super family> getMembers() {
Collection<? super family> f;
f = processing.getInstance().getAllPeopleByClass(family.class);
return f;
}
}
UPD: Use ansuper
wildcard, when you only put
values into a structure. Use anextends
wildcard , when you only get
values out of a structure. And don't use wildcards when you use both get
and put
.
Upvotes: 1
Reputation: 53694
public <T> Collection<T> getAllPeopleByClass(Class<T> clazz) {
Collection<T> peopleCollection = new ArrayList<T>();
for(people p : getList(clazz)) {
peopleCollection.add(clazz.cast(p));
}
return peopleCollection;
}
Upvotes: 2