Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果模板是返回值,则为模板类型(Java)_Java_Templates_Classcastexception - Fatal编程技术网

如果模板是返回值,则为模板类型(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,您不需要在类级别声明泛型类型参数,就可以在方法级别声明泛型类型参数。请根据注释解释问题…根据注释解释问题。。。