所以我有一张地图:
Map<String, Class> format = new HashMap<String, Class>();
我会像这样添加元素:
format.put("Vendor Number", Integer.class);
format.put("Vendor Dispatch", Date.class);
....
我有一个通用的方法如下:
public static <T> T verifyType(String name, Class<T> type) {
if (type == Integer.class) {
return type.cast(new Integer(Integer.parseInt(name)));
}
......
return null;
}
现在这段代码很好用,没有编译器问题:
Integer i = verifyType("100",Integer.class);
但是,当我尝试这个时:
Integer i = verifyType("100",format.get("Vendor Number"));
OR
Class type = Integer.class
Integer i = verifyType("100",type);
编译器向我显示此警告: 类型安全:通用方法verifyType(String,Class)的未经检查的调用verifyType(String,Class)
这让我感到困惑......请帮助......
答案 0 :(得分:8)
变化:
Class type = Integer.class
Integer i = verifyType("100",type);
到
Class<Integer> type = Integer.class
Integer i = verifyType("100",type);
通过仅将类型声明为“类”,您将丢失泛型参数,而verifyType()方法无法推断类,因此未经检查的警告。
这个问题:
Map<String, Class> format = new HashMap<String, Class>();
format.put("Vendor Number", Integer.class);
format.put("Vendor Dispatch", Date.class);
Integer i = verifyType("100",format.get("Vendor Number"));
由于类型擦除,无法真正解决。编译器无法根据运行时消失的泛型参数来推断类型。这是因为Java泛型只不过是用于投射的烟雾和镜子。
答案 1 :(得分:4)
您必须对Class的引用进行泛化。例如:
Class<Integer> type = Integer.class
Integer i = verifyType("100",type);
会正常工作。
一如既往:
Map<String, Class<?>> format = new HashMap<String, Class<?>>();
然而,这将永远不会奏效:
Integer i = verifyType("100",format.get("Vendor Number"));
因为格式未定义为:
Map<String, Class<Integer>>
如果是的话,铸造会起作用,但设计毫无意义。
最接近的是:
Integer i = verifyType("100",(Class<Integer>) format.get("Vendor Number"));
但是,你必须得到一个编译器警告,你必须这样做 - 它本身就是一个不安全的演员。编译器正在接受你的说法,即format.get语句将返回一个整数。如果你确定,那就是不安全的演员阵容。如果你想摆脱编译器警告,你可以这样做:
Class<?> type = format.get("Vendor Number");
Integer i = null;
if (type == Integer.class) {
i = verifyType("100", Integer.class);
} else {
//What do you want to do?
}
答案 2 :(得分:2)
这是因为你的HashMap返回了一个
Class
对象,但验证函数需要
Class<T>
对象。
答案 3 :(得分:1)
你得到这个错误的原因是,在第一种情况下,编译器看到你传递了一个Class对象,并且能够在编译时将T绑定到Integer,但在第二种情况下,编译器只看到你正在传递它是一个Class对象。
在一天结束时,你将无法做到
Integer i = verifyType("100",format.get("Vendor Number"));
以类型安全的方式,因为编译器不能知道你会得到一个Integer(如果有人在那次调用之前做了format.put(“Vendor Number”,X.class)会怎么样?)
答案 4 :(得分:1)
对我来说很奇怪,你的编译器在线
Integer i = verifyType("100",format.get("Vendor Number"));
抱怨未经检查的调用但未显示类似“类型不匹配:无法从Object转换为整数”的错误。
这条线对我来说没有意义。如果将Date.class作为第二个参数接收,您希望verifyType返回什么?还有一个Integer(那么verifyType的返回类型是无效的)?还是约会?如果您期望日期,编译器应该如何知道
format.get("Vendor Number");
返回Integer.class,但
format.get("Vendor Dispatch");
返回Date.class
调用
Integer i = verifyType("100",format.get("Vendor Dispatch"));
必须失败,因为Date不是整数。所以,在我看来(以及我的编译器的意见)编译
Integer i = verifyType("100",format.get("Vendor Number"));
必须失败。
答案 5 :(得分:0)
类Class
本身就是一个泛型类。如果你试试
Class<Integer> type = Integer.class;
Integer i = verifyType("100", type);
它应该更好。输入参数的泛化使编译器相信你知道自己在做什么,足以让你的代码在没有警告的情况下编译。
您还可以通过使用
抑制警告来说服编译器@SuppressWarning("unchecked")
在特定的代码或方法行之前。