从可迭代<?>到可迭代的转换<Object>总是安全的吗?



Iterable<?>Iterable<Object>的铸造总是安全的吗?

看起来是这样,因为我看不出有什么办法滥用它来产生意想不到的ClassCastException,但我想我错过了一些东西。

Iterable 的情况下,是的,因为它没有任何接受T的方法,只有返回T的方法(好吧,通过它的迭代器)。编辑:见下文。

Java没有协变类与逆变类的正式概念,这就是为什么它无法区分Iterable<T>List<T>(后者从List<?>转换为List<Object>是不安全的)。由于它没有这种区别,因此它被迫警告您演员表可能不安全。毕竟,不安全并不意味着事情中断,它只是意味着编译器不能保证它们不会

编辑:maaartinus发现了一个很好的反例。仅当可迭代对象不可变时,上述情况才成立;但是,当然,不可变类型通常是协变的(即使Java不承认这一点,因为它不承认不变性)。

现在我知道是什么困扰着我:

Integer blown() {
    List<Integer> intList = new ArrayList<Integer>();
    Iterable<?> iterable = intList;
    @SuppressWarnings("unchecked") // This cast should be safe, shouldn't it?
    Iterable<Object> objectIterable = (Iterable<Object>) iterable;
    safeMethod(objectIterable);
    return intList.get(0);
}
// This method is definitely fine, no unchecked cast.
private void safeMethod(Iterable<Object> objectIterable) {
    if (objectIterable instanceof List) {
        List<Object> list = (List<Object>) objectIterable;
        list.add("blown!");
    }
}

所以演员阵容是安全的,只要你不抛弃,不要让不安全的东西逃脱。

最新更新