[英]Convert java legacy code to generic - how to replace Object with type?
//遺留代碼
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
}
那么,這樣做的正確方法是什么?
這確實不可能。 您需要以某種方式將“具體” T
作為方法參數傳遞,以便在運行時期間知道實際類型。 常用的方法是將它作為Class<T>
傳遞,這樣就可以使用Class#cast()
:
<T> T getCacheValue(String name, Class<T> type) {
return type.cast(getServletContext().getAttribute(name));
}
您可以按如下方式使用它:
Double value = getCacheValue("x", Double.class);
Map泛型支持地圖的所有值上的類型,而不是特定值的不同類型。 你可以在這里看到如何偽造它。 基本上,這個想法是你必須在密鑰上具有類型安全性,其中密鑰上有一個泛型類型,它只是為了與值相關聯而存在。
在一天結束時,如果沒有不安全的演員陣容,你將無法做到這一點,但你可以這樣做,使得演員陣容的問題極不可能,並且對於你班級的用戶。
實際上也編譯:
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");
}
}
這有點毫無意義(也許你添加了一個類型檢查),但我發現它很有趣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.