有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java泛型cast to List<SomeType>在cast to SomeType not时发出未经检查的强制转换警告

为什么会这样:

public <T> List<byte[]> getData(T data) {
    Location loc = (Location) data;
    // ...
}

在以下情况下,不会生成任何警告:

public <T> List<byte[]> getData(T data) {
    List<ScanResult> scanRes = (List<ScanResult>) data;
    // ...
}

生成Type safety: Unchecked cast from T to List<ScanResult>

我怎样才能平息这个警告呢
作为一种设计,这种方法是一种气味吗

public <T> List<byte[]> getData(T data)

是在具有不同数据类型的不同类中实现的接口方法-所有实现的第一行就是这样的强制转换


共 (2) 个答案

  1. # 1 楼答案

    您会收到警告,因为cast(List<ScanResult>) data不安全。由于type erasureList<ScanResult>将在运行时List,因此不会对列表的元素类型进行真正的类型检查。也就是说,即使您获得List<String>作为参数,该强制转换也将成功,之后当您尝试访问列表时,您将获得ClassCastException

    ScanResult result = data.get(0); // ClassCastException: String
    

    避免这种情况的一种方法是使接口通用:

    public interface DataProvider<T> {
        public List<byte[]> getData(T data);
    }
    

    然后在实现中定义特定的类型参数:

    public class DataProviderFromLocation implements DataProvider<Location> {
        public List<byte[]> getData(Location data) {
        }
    }
    
    public class DataProviderFromScanResultList implements DataProvider<List<ScanResult>> {
        public List<byte[]> getData(List<ScanResult> data) {
        }
    }
    

    我不知道它是否适合你的需要

  2. # 2 楼答案

    来自安吉丽卡·兰格的Java Generics FAQs

    We are prepared to cope with ClassCastException s when there is a cast expression in the source code, but we do not expect ClassCastException s when we extract an element from a list of strings. This sort of unexpected ClassCastException is considered a violation of the type-safety principle. In order to draw attention to the potentially unsafe cast the compiler issues an "unchecked" warning when it translates the dubious cast expression.

    因此,我的第一个问题的答案是,如果类不兼容,对SomeType的转换将失败,而在运行时只是List scanRes = (List) data;List<ScanResult> scanRes = (List<ScanResult>) data;如果data任何列表实现,则不会失败,但可能会在代码库的远程和完全不相关的部分导致CCE,因此它将是真的很难调试-因此发出警告

    另一种说法是(作者@ericksonhere):

    By doing your own cast up front, you're "complying with the warranty terms" of Java generics: if a ClassCastException is raised, it will be associated with a cast in the source code, not an invisible cast inserted by the compiler.