我在我的程序中使用一个系统,其中有一个中央“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();
}
}
}
}
答案 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
。