我想知道什么是模板变量的数据类型,如果返回被设置为一个模板。我有一个代码看到这个地方,但我不知道它在哪里投从会话检索到的值。

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。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top