Question

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!

Was it helpful?

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

OTHER TIPS

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.

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;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top