在泛型类返回根类中创建Java方法

时间:2016-02-21 04:28:28

标签: java generics language-lawyer

我在我的程序中使用一个系统,其中有一个中央“Manager”类,用于跟踪其他类,然后是其他处理程序各种功能的类(称为“功能”类)。我在一个公共库中有一个抽象的Manager类,它实现了几个基本的“Feature”类。其中一个要素类需要通用参数,其他要素类需要能够访问所述通用参数。

当我直接访问此泛型参数的单个实例时,这不是问题。当我需要访问Set时,会出现此问题。

以下是一个例子:

public abstract class AbstractManager<T extends User>{
    private UserManager<T> userManager;

    public UserManager<T> getUserManager(){
        return userManager;
    }
}

-

public class UserManager<T extends User>{
    private HashMap<String, T> userMap;

    public UserManager(){
        userMap = new HashMap<>();
    }

    public T getUserEntry(String name){
        return userMap.get(name);
    }

    public Set<Map.Entry<String, T>> getUserEntries(){
        return userMap.entrySet();
    }

}

-

public class AnotherFeatureClass{
    private AbstractManager manager;

    public AnotherFeatureClass(AbstractManager manager){
        this.manager = manager;
    }

    public void doSomething(){
        User user = manager.getUserManager().getUserEntry("username"); //this works fine
    }   

    public void doSomethingElse(){ //this method does something to every user

        //I would like something like this -- I don't imagine it is impossible since whatever T is it extends user
        for(Set<Map.Entry<String, T>> entry : manager.getUserManager().getUserEntries()){
            entry.getValue().doSomething();
        }

        //I'm using this right now -- it is very messy probably has many bugs that do who knows what and I can't help but assume there is a better way to do it
        for(Object obj : manager.getUserManager().getUserEntries()){
            try{
            @SuppressWarnings("unchecked")
            Set<Map.Entry<String, T>> entry = ((Set<Map.Entry<String, T>>) obj);
            entry.getValue().doSomething();
            }catch(ClassCastException e){
            e.printStackTrace();
            }
        }
    }

}

1 个答案:

答案 0 :(得分:0)

基本规则是从不使用原始类型。这并不意味着您必须始终指定具体类型,也不必为每个类添加类型参数。

这就是通配符的用途:

public class AnotherFeatureClass {
    private AbstractManager<? extends User> manager;

    public AnotherFeatureClass(AbstractManager<? extends User> manager){
        this.manager = manager;
    }

    public void doSomething() {
        User user = manager.getUserManager().getUserEntry("username"); //still works fine
    }   

    public void doSomethingElse() {
        for(Map.Entry<String, ? extends User> entry:
                                              manager.getUserManager().getUserEntries()) {
            // assuming doSomething() is a method declared in User
            entry.getValue().doSomething();
            // e.g. you could also write
            User u = entry.getValue();
        }
    }
}

因此AnotherFeatureClass不是通用的,可能与任意类型的AbstractManager一起使用,但是,由于AnotherFeatureClass不了解实际类型,因此无法添加新的User 1}}实例(适当的,未知的(子)类型)到管理器。但是,使用基本类型User读取和处理用户是有效的,因为实际类型必须可分配给User

相关问题