模板的类型,如果模板的返回值(JAVA)
-
19-09-2019 - |
题
我想知道什么是模板变量的数据类型,如果返回被设置为一个模板。我有一个代码看到这个地方,但我不知道它在哪里投从会话检索到的值。
public class RequestObject {
public <T> T getFromSessionMap(String sessionKey) {
return (T)session.getAttribute(sessionKey);
}
}
此以外的代码是:
MyClassType type = request.getFromSessionMap("abc");
线投射到我的对象时遇到ClassCastException异常。但是,当我加入到观看session.getAttribute(“ABC”),则说明该类型是MyClassType。任何帮助,将不胜感激。
显然使用模板这个特殊的代码使getFromSessionMap的返回变量类型,因此不需要铸造。这适用于所有的情况下,却突然在代码中的一个部分失败。
解决方案
显然使用该特殊代码 模板使返回 getFromSessionMap变量类型和 因此没有必要铸。
从根本上说,那里的必须是强>类型转换某处获得session.getAttribute(sessionKey)
并MyClassType
所述分配的结果之间。 Java语言(以及JVM)的将不允许强>一些对象,它是一个不实例MyClassType
(或其子类型)将被分配给一个MyClassType
变量。
不管你怎么写的代码,类型转换已经发生。并且由于属性(显然)不是MyClassType
(或子类型),则得到一个ClassCastException
。
所以,真正的问题是,你为什么不得到一个编译错误?而答案是@SuppressWarnings("unchecked")
!如果你删除了警告,你会得到一个“不安全的类型转换”错误消息这一行:
return (T) session.getAttribute(sessionKey);
事实上,Java的不能做(真正的)类型转换为泛型类型。这是警告/错误消息就是有指出。事实上,一旦代码被编译,这代码
public <T> T getFromSessionMap(String sessionKey) {
return (T)session.getAttribute(sessionKey);
}
在意义实际上没有什么不同,从这样的:
public Object getFromSessionMap(String sessionKey) {
return session.getAttribute(sessionKey);
}
从技术上讲这被称为 “类型擦除”。
那么,在类型检查/类型转换实际发生?答案是在这条线:
MyClassType type = request.getFromSessionMap("abc");
即使你还没有在这里写一个类型转换,由Java编译器生成的代码做一个类型转换分配给type
前值。它必须。因为只要它知道,它被分配的实例可以是任何对象类型。
其他海报建议增加一类参数getFromSessionMap
。就其本身而言这样做的绝对没有的。如果还替换的方法的主体:
return clazz.cast(session.getAttribute(sessionKey));
您会导致真正做一个真正的类型检查的方法。但是,这只是原因ClassCastException
在不同的地方被抛出。而赋值语句的仍然会做一个隐式类型转换!! 的
其他提示
在的问题的例子,返回类型为T
。擦除类型将被作为Object
,含蓄,T extends Object
。实际铸在所调用的方法的字节码进行(可以使用javap -c
地看到)。
一般情况下,你应该保持在尽可能小的会议“顶级”对象的数量。一个这样做的好处,是有不再需要哈克的方法,如这些。
任何帮助,将理解的,因为我的代码遇到ClassCastException异常。
如果你得到一个ClassCastException
,这意味着你想在下面的代码投的东西弄成它不是,如:
Map session = new HashMap();
session.put("date", "2009-11-12");
Date today = (Date) session.get("date"); // tries to convert String to Date
在ClassCastException
应该有一个启发详细消息,如“java.lang.String中不能转换到java.util.Date”。
您使用的方法体( '(T)session.getAttribute(sessionKey)'的)。
内投型这意味着你明确地告诉编译器的“我绝对相信返回的对象-A T和准备来处理错误,如果它不是” 的。
在这里你关于属性类型假设是不正确的,你得到了一个错误。所以,一切都是正确的,运行时已经为您提供了不实属性的对象类型的 IS-A 的MyClassType。