如果模板是返回值,则为模板类型(Java)
我想知道如果返回设置为模板,那么模板变量的数据类型是什么。我在某个地方的代码中看到过这一点,但我不知道它将从会话中检索到的值转换到了哪里如果模板是返回值,则为模板类型(Java),java,templates,classcastexception,Java,Templates,Classcastexception,我想知道如果返回设置为模板,那么模板变量的数据类型是什么。我在某个地方的代码中看到过这一点,但我不知道它将从会话中检索到的值转换到了哪里 public class RequestObject { public <T> T getFromSessionMap(String sessionKey) { return (T)session.getAttribute(sessionKey); } } 当转换到我的对象时,该行遇到ClassCastExcept
public class RequestObject {
public <T> T getFromSessionMap(String sessionKey) {
return (T)session.getAttribute(sessionKey);
}
}
当转换到我的对象时,该行遇到ClassCastException。但是当我添加到watch session.getAttributeabc时,它显示类型是MyClassType。任何帮助都将不胜感激
显然,这个使用模板的特殊代码使getFromSessionMap的返回成为变量类型,因此不需要强制转换。这适用于所有情况,但在代码的一部分突然失败。在问题的示例中,返回类型是T。删除的类型将是Object,隐式地是T extends Object。实际的强制转换是在调用方法的字节码中执行的,您可以使用javap-c来查看
通常,会话中顶级对象的数量应尽可能少。这样做的好处之一是,不再需要像这样的黑客方法。在问题的示例中,返回类型是T。删除的类型将是Object,隐式地,T扩展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
任何帮助都将不胜感激,因为我的代码遇到了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。在方法主体“Tsession.getAttributesessionKey”中使用类型转换 这意味着您明确地对编译器说“我绝对确定返回的对象是-A T,如果不是,则准备好处理错误”
在这里,您对属性类型的假设是错误的,您得到了一个错误。因此,一切都是正确的,运行时已经为您提供了真正的属性对象类型,而不是is-MyClassType。您在方法体“Tsession.getAttributesessionKey”中使用类型转换 这意味着您明确地对编译器说“我绝对确定返回的对象是-A T,如果不是,则准备好处理错误” 在这里,您对属性类型的假设是错误的,您得到了一个错误。所以,一切都是正确的,运行时已经为您提供了真正的属性对象类型,而不是一个MyClassType 显然这是一个特殊的代码 模板返回 getFromSessionMap变量类型和 因此不需要演员阵容 从根本上说,在获取session.getAttributesessionKey的结果和分配给MyClassType之间必须有一个类型转换。Java语言和JVM将不允许将非MyClassType实例或其子类型的对象分配给MyClassType变量 无论您如何编写代码,都必须进行类型转换。由于该属性显然不是MyClassType或子类型,因此您将得到一个ClassCastException 所以真正的问题是,为什么没有得到编译错误?答案是@suppressWarningUnchecked!如果删除该警告,则会收到此行的不安全类型转换错误消息:
return (T) session.getAttribute(sessionKey);
MyClassType type = request.getFromSessionMap("abc");
事实上,Java不能对泛型类型进行真正的类型转换。这就是警告/错误信息要指出的。事实上,一旦代码被编译,这个代码
public <T> T getFromSessionMap(String sessionKey) {
return (T)session.getAttribute(sessionKey);
}
从技术上讲,这称为类型擦除
那么类型检查/类型转换实际发生在哪里呢?答案是这样的:
return (T) session.getAttribute(sessionKey);
MyClassType type = request.getFromSessionMap("abc");
即使您没有在这里编写类型转换,Java编译器生成的代码也会在将值分配给类型之前进行类型转换。这是必须的。因为据它所知,它正在分配的实例可以是任何对象类型
其他海报建议在getFromSessionMap中添加一个类参数。这本身完全没有任何作用。如果还将方法主体替换为:
return clazz.cast(session.getAttribute(sessionKey));
您将使该方法实际执行实类型检查。但这只会导致ClassCastException被抛出到不同的位置。赋值语句仍将执行隐藏类型转换
显然这是一个特殊的代码
模板返回o
F
getFromSessionMap变量类型和
因此不需要演员阵容
从根本上说,在获取session.getAttributesessionKey的结果和分配给MyClassType之间必须有一个类型转换。Java语言和JVM将不允许将非MyClassType实例或其子类型的对象分配给MyClassType变量
无论您如何编写代码,都必须进行类型转换。由于该属性显然不是MyClassType或子类型,因此您将得到一个ClassCastException
所以真正的问题是,为什么没有得到编译错误?答案是@suppressWarningUnchecked!如果删除该警告,则会收到此行的不安全类型转换错误消息:
return (T) session.getAttribute(sessionKey);
MyClassType type = request.getFromSessionMap("abc");
事实上,Java不能对泛型类型进行真正的类型转换。这就是警告/错误信息要指出的。事实上,一旦代码被编译,这个代码
public <T> T getFromSessionMap(String sessionKey) {
return (T)session.getAttribute(sessionKey);
}
从技术上讲,这称为类型擦除
那么类型检查/类型转换实际发生在哪里呢?答案是这样的:
return (T) session.getAttribute(sessionKey);
MyClassType type = request.getFromSessionMap("abc");
即使您没有在这里编写类型转换,Java编译器生成的代码也会在将值分配给类型之前进行类型转换。这是必须的。因为据它所知,它正在分配的实例可以是任何对象类型
其他海报建议在getFromSessionMap中添加一个类参数。这本身完全没有任何作用。如果还将方法主体替换为:
return clazz.cast(session.getAttribute(sessionKey));
您将使该方法实际执行实类型检查。但这只会导致ClassCastException被抛出到不同的位置。赋值语句仍将执行隐藏类型转换 问题是,当我添加到watch session.getAttributeabc时,它显示类型是MyClassType。是的,这将是对类异常的最初反应。我也是这么想的。ClassCastException详细信息是。。。什么?问题是当我添加到watch session.getAttributeabc时,它显示类型是MyClassType。是的,这将是对类异常的最初反应。我也是这么想的。ClassCastException详细信息是。。。什么?我想是T型铸造的,但什么是T型?对象?T不是类型,T是参数化类型。您无法在运行时查询T的类型,即ala,类型erasure。用于输入属性abc的代码没有输入MyClassType类型,或者在输入sessionmap后被某些内容更改了。@Nassign-仔细阅读我的答案。当您编写T时,不会发生真正的类型转换。您所做的是不安全的类型转换。。。a在这种情况下不可操作。@Stephen C,谢谢你的详细解释。我想知道为什么Java编译器甚至允许在类没有模板类定义的情况下生成这个构造。@Nassign-在Java中,您不需要在类级别声明泛型类型参数,就可以在方法级别声明泛型类型参数。我想它被转换为类型t,但什么是类型t?对象?T不是类型,T是参数化类型。您无法在运行时查询T的类型,即ala,类型erasure。用于输入属性abc的代码没有输入MyClassType类型,或者在输入sessionmap后被某些内容更改了。@Nassign-仔细阅读我的答案。当您编写T时,不会发生真正的类型转换。您所做的是不安全的类型转换。。。a在这种情况下不可操作。@Stephen C,谢谢你的详细解释。我想知道为什么Java编译器甚至允许在类没有模板类定义的情况下生成这个构造。@Nassign-In Java,您不需要在类级别声明泛型类型参数,就可以在方法级别声明泛型类型参数。请根据注释解释问题…根据注释解释问题。。。