指定类对象的类型

Dav*_*veH 5 java generics

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

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

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

就这段代码而言,我收到编译器警告(类型安全:列表类型的表达式需要未经检查的转换才能符合列表)。

我知道我可以通过添加注释来解决这个问题@SuppressWarnings("unchecked"),但是有没有一种方法可以通过更改 的声明来修复它List.class

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

Tag*_*eev 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;
}
Run Code Online (Sandbox Code Playgroud)

在这个方法中仍然是必要的,但它@SuppressWarnings是“库”方法,所以在这里没问题。但是在业务代码中您现在可以使用:

List<Message> list = checkElements(oldExchange.getProperty("p",List.class), Message.class);
Run Code Online (Sandbox Code Playgroud)

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