Search code examples
javagenericstypesextendsmismatch

How to create the correct return type?


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!


Solution

  • 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;
    }