2010-05-06 28 views
3

//遺留代碼將java遺留代碼轉換爲泛型 - 如何用類型替換Object?

void setCacheValue(String name, Object value){ 
    getServletContext().setAttribute(name, value); 
} 
Object getCacheValue(String name){ 
    return getServletContext().getAttribute(name); 
} 

//所以我要使用通用的 「類型安全」

// first, set method seems working perfectly 
<T> void setCacheObject(String name, T value){ 
    getServletContext().setAttribute(name, value); 
} 

//然後,來這裏的麻煩

<T> T getCacheValue(String name){  
    // of course, I cannot change servlet class - it returns Object type 
    Object value = getServletContext().getAttribute(name); 
    // would this work:  
    return (T) value; 
    // this cast is meaningless... but how should I do it? 
} 

//這是我在清潔呼叫代碼中實現的目標:

{ 
    double x = 1.2; 
    setCacheValue("x", x); 
    //... 
    // later 
    Double value = getCacheValue("x"); 
    // too bad cannot use primitive type - it cannot handle null 

}

那麼,什麼是這樣做的正確方法是什麼?

回答

3

這確實不可能。您需要以某種方式將「具體」T作爲方法參數傳遞,以便在運行時知道實際類型。常用的方法是把它當作Class<T>,這樣就可以利用Class#cast()

Double value = getCacheValue("x", Double.class); 
+0

+1常見問題 - 標準方法 – leonbloy 2010-05-06 19:02:05

+0

很好。我發現類投射做了兩件事:它抑制了編譯警告,並且它在運行時檢查了類型 - 儘管它可能爲時已晚,但總比不檢查更好。 (價格不得不通過一個額外的參數) – joejax 2010-05-06 19:34:02

0

地圖泛型支持在地圖上的所有值的類型:

<T> T getCacheValue(String name, Class<T> type) { 
    return type.cast(getServletContext().getAttribute(name)); 
} 

您可以按如下方式使用它,對於特定的值而言不是一種不同類型。你可以看到如何僞造here。基本上這個想法是你必須在鍵上具有類型安全性,其中鍵有一個通用類型,只存在與值關聯。

在一天結束時,如果沒有不安全的演員,你將無法做到這一點,但是你可以這樣做,使演員出現問題的可能性極小,對班級的用戶是類型安全的。

+0

有趣的想法。請注意,servlet上下文的屬性映射只接受String鍵。您需要在其中放置另一個地圖並相應地使用它。 - – BalusC 2010-05-06 19:20:16

0

事實上,編譯,太:

public class Test 
{ 
    <T> T getCacheValue(String name){  
     // of course, I cannot change servlet class - it returns Object type 
     Object value = getServletContext().getAttribute(name); 
     // would this work:  
     return (T) value; 
     // this cast is meaningless... but how should I do it? 
    } 

    public static void main(String... args) 
    { 
     Test t = new Test(); 
     Double double = t.<Double>getCacheValue("Double"); 
    } 
} 

這是一種毫無意義的(也許如果你添加一個類型檢測),但我覺得它很有趣知道。