在类对象

时间:2015-09-04 08:01:41

标签: java generics

以下代码调用Camel Exchange上的setProperty方法

List<Message> list = oldExchange.getProperty("p",List.class);

目的是检索我之前针对List实例存储的Exchange对象。

正如此代码所示,我收到编译器警告(类型安全:类型List的表达式需要未经检查的转换以符合List)。

我知道我可以通过添加@SuppressWarnings("unchecked")注释来消除这种情况,但有没有办法可以通过更改List.class的声明来修复它?

getProperty方法具有以下签名 <T> T getProperty(String name, Class<T> type)

2 个答案:

答案 0 :(得分:2)

不幸的是,这不可能完成 - 泛型类型没有类文字表达式。

如果您的代码中有很多此类调用,您可能需要创建一个实用程序方法来仅在一个地方禁止警告:

@SuppressWarnings("unchecked")
static <T> T  myGetProperty(String name, Class<?> type) {
    return (T) getProperty(name, type);
}

然后这个电话没有警告:

List<String> listOfStrings = myGetProperty("a", List.class);

但是,您需要记住它确实是未选中,因此您无法确定列表中的元素是字符串。

答案 1 :(得分:1)

遗憾的是,您的演员阵容不安全,因为虽然您知道返回的对象具有List类型,但您无法确定此列表的所有元素都具有Message类型。因此,当您编写类似ClassCastException

的内容时,您可能会在以后发现意外Message m = list.get(0);

为了使你的代码健壮,你必须检查所有现有的列表元素,然后你可以像这样进行未经检查的转换:

public static <T> List<T> checkElements(List<?> list, Class<T> elementClass) {
    for(Object e : list) {
        elementClass.cast(e); // throw CCE on wrong element
    }
    @SuppressWarnings("unchecked")
    List<T> result = (List<T>)list;
    return result;
}

此方法中仍然需要@SuppressWarnings,但它是“库”方法,所以这里没关系。但是,在商业代码中,您现在可以使用:

List<Message> list = checkElements(oldExchange.getProperty("p",List.class), Message.class);

这种方法的缺点是需要一些时间来检查每个元素的类型。如果您100%确定自己拥有正确的列表,那么只需在原始代码中使用@SuppressWarnings即可。