如何创建正确的返回类型?

时间:2013-06-19 14:30:03

标签: java generics types extends mismatch

我会在底部发布我的问题。

以下是其他类扩展的类。

public class people {

    class family extends people {   
    }

    class friends extends people {  
    }

    class coworkers extends people {    
    }
}

下面是具有getAllPeopleByClass方法的类,该方法由选择类中的getMembers()方法调用:

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

最后,使用处理的类:

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

我的问题是我在每个getMembers()方法中都遇到了getAllPeopleByClass调用的类型不匹配。

我试过这个:

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

这样可行,但是我得到了一个强制警告,我不想要它,我也不想压制它。这是我最接近解决问题的方法。此外,getMembers()的返回类型必须保持原样。有没有人有办法在没有任何警告的情况下这样做?或者甚至以某种方式处理这个问题?谢谢!

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

使用super关键字:

public class familySelection {
  public Collection<? super family> getMembers() {
    Collection<? super family> f;
    f = processing.getInstance().getAllPeopleByClass(family.class);
    return f;
  }
}

UPD:当您只有super个值进入结构时,请使用put通配符。当结构中只有extends个值时,请使用get通配符。当您同时使用getput时,请不要使用通配符。

答案 2 :(得分:0)

我会选择这个版本。它还需要警告抑制,但我认为这是更好的地方。

我也允许自己改变你的Singleton实现。如果你真的想这样做,可以考虑使用枚举。

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

和familySelection:

public class familySelection {
    public Collection<family> getMembers() {
        Collection<family> f = processing.getInstance().getAllPeopleByClass(family.class);
        return f;
    }
}