[英]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.