类型推断在java中究竟是如何工作的?
我正在尝试创建如下方法:类型推断在java中究竟是如何工作的?,java,generics,type-inference,Java,Generics,Type Inference,我正在尝试创建如下方法: public <T> T getInstance(String key) { Type type = new TypeToken<T>(){}.getType(); return deserialize(key, type); } 但在某些情况下,getInstance()方法返回从未提及过的Double(更准确地说,序列化和反序列化使用google的库,初始对象是Integer的实例)。因此,我得到了ClassCastExcept
public <T> T getInstance(String key) {
Type type = new TypeToken<T>(){}.getType();
return deserialize(key, type); }
但在某些情况下,getInstance()
方法返回从未提及过的Double
(更准确地说,序列化和反序列化使用google的库,初始对象是Integer
的实例)。因此,我得到了ClassCastException
那么,在这种情况下,类型推断究竟是如何工作的?为什么类型见证不起作用?是否可以从外部上下文推断类型而不指定Class.Class
作为参数
精化:
经过一些研究,帮助我更好地理解了这个主题。这里的一般问题是,没有任何东西可以限制输出与输入相关 因此,这是有效的:
Integer i = container.<Integer>getInstance(mKey); // I doubt you even need the <Integer>
输出:
Ideone$TypeToken<T>
Ideone$TypeToken<T>
true
Ideone$TypeToken
Ideone$TypeToken
真的
在代码中,Type Type=newtypetoken(){}.getType()
没有获取呼叫站点类型的TypeToken
,它只是获取t
。所以你没有得到一个TypeToken
从编译的意义上讲,这是可行的,但从它不做你想让它做的事情的意义上讲,它是行不通的
正确执行此操作的方法是将
TypeToken
作为方法参数注入。在呼叫站点,它变得非常麻烦;但这是使用删除类型的语言所付出的代价。这根本不起作用。由于擦除,您无法使用类型变量创建类型标记。@Andy Turner嗯,该方法可以编译。唯一的问题是返回类型错误。此外,我看到使用其他程序员的泛型类型创建TypeToken;至少,正如你所发现的那样,它没有起到有效的作用。我应该更准确地说,您不能使用类型变量创建类型标记,并期望它捕获除类型变量之外的任何内容。签出:“字符串”类型标记的“类型”与“整数”类型标记相同,因为它们捕获的是类型变量,而不是调用站点类型。@Andy Turner好的,我知道了,这很有意义。谢谢。我只是想知道,我是否能够将对象作为类型发送到反序列化器,但在return语句中将其转换为(T),这将从外部上下文推断出来?我尝试了后者。此外,我还尝试不使用泛型,只返回对象。两者都不起作用,在某些情况下,它仍然返回双精度。奇怪的
String s = container.<String>getInstance(mKey);
abstract static class TypeToken<T> {
Type getType() {
return getClass().getGenericSuperclass();
}
}
static <T> TypeToken<T> getTypeToken() {
return new TypeToken<T>() {};
}
public static void main (String[] args) throws java.lang.Exception
{
TypeToken<String> stringTypeToken = getTypeToken();
TypeToken<Integer> integerTypeToken = getTypeToken();
System.out.println(stringTypeToken.getType());
System.out.println(integerTypeToken.getType());
System.out.println(stringTypeToken.getType().equals(integerTypeToken.getType()));
}
Ideone$TypeToken<T>
Ideone$TypeToken<T>
true