2013-06-19 23 views
1

我會在底部發表我的問題。如何創建正確的返回類型?

下面是其他類的擴展類。

public class people { 

    class family extends people { 
    } 

    class friends extends people { 
    } 

    class coworkers extends people {  
    } 
} 

下面是具有得到由getMembers調用(該方法getAllPeopleByClass)方法在選擇的類的類:

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

我的問題是,我從getAmbers()方法的每個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()的返回類型必須保持原樣。有沒有人有辦法做到這一點,沒有任何警告?或者甚至以某種方式處理這一般?謝謝!

+0

設計中的主要問題是,泛型是編譯時類型強制,但正在執行的類型在運行時檢查。也許考慮有3種單獨的方法來返回每種類型的集合。 – nitegazer2003

回答

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

不起作用。 – darijan

+0

你甚至讀過:這有效,但我得到了一個警告,我不想要,我不想壓制它。 – darijan

+1

@darijan - 您是否完整閱讀了我的(更新後)答案? 「由於Java泛型的限制......」。這是它可以是「最正確的」。 – jtahlborn

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時,請勿使用通配符。

+0

這會編譯,但它不會很有用。擁有某種類型的集合,這種集合是家族的超類,比起根本不使用泛型更有用。 – jtahlborn

+0

OP確實表示getMembers()的返回類型必須保持爲 – nitegazer2003

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

感謝您的發帖。爲什麼你喜歡在可以一併消除的時候發出警告? –

+0

我在@jtahlborn編輯他的版本之前開始寫我的回覆。 –

+0

還有一件事:可能在大多數情況下,這並不重要,但他必須爲集合中的每個對象執行cast(p)方法。而且他可以做到這一點而不冒着ClassCastException的風險,只是因爲他知道getList(clazz)方法的實現。所以他也在做不加控制的演員,這並不那麼明顯 - 而且你不必壓制它。 –