3

// 遗留代码

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

}

那么,这样做的正确方法是什么?

4

3 回答 3

3

这确实是不可能的。您需要以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);
于 2010-05-06T18:59:08.813 回答
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");
    }
}

这有点毫无意义(也许如果你添加一个类型检查),但我发现它很有趣。

于 2010-05-06T19:19:42.163 回答
0

映射泛型支持映射所有值的类型,而不是特定值的不同类型。你可以在这里看到如何伪造它。基本上这个想法是你必须在键上具有类型安全性,其中键上有一个泛型类型,它的存在只是为了与值相关联。

归根结底,如果没有不安全的演员表,您将无法做到这一点,但是您可以以一种极不可能出现演员表问题的方式以及对你班级的用户。

于 2010-05-06T19:04:19.623 回答