从Iterable <! - ? - >转换为Iterable <object>始终安全吗?</object>

时间:2013-10-17 18:14:43

标签: java generics casting

Iterable<?>Iterable<Object>的投射始终安全吗?

它看起来像是,因为我无法看到任何方法如何滥用它来产生意外的ClassCastException,但我想我错过了什么。

2 个答案:

答案 0 :(得分:6)

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

Java没有协变类和逆变类的正式概念,这就是为什么它无法区分Iterable<T>List<T>(后者不是安全地从List<?>投射到List<Object>)。由于它没有这种区别,它被迫警告你,演员阵容可能不安全。毕竟,不安全并不意味着中断,这只是意味着编译器无法保证不会

编辑: maaartinus发现了一个很好的反例。只有Iterable是不可变的,上面才是真的;但是,当然,不可变类型通常是协变的(即使Java不承认这一点,因为它不能识别不变性)。

答案 1 :(得分:4)

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

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!");
    }
}

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