简体   繁体   English

如果B扩展了A,则不能将List强制转换<A>为List <B>(很有意义),但是为什么一个可以将List强制转换</a> <? extends A> <A><B>列出<B>?</a>

[英]If B extends A, one cannot cast List<A> to List<B> (makes sense), but then why can one cast List<? extends A> to List<B>?

If a class B extends class A , one cannot cast List<A> to List<B> (cast 1 below). 如果类B扩展了类A ,则不能将List<A>List<B> (下面的广播1)。 This makes sense, because if it were allowed, then one could read a B from the list even if it contained none. 这是有道理的,因为如果允许,那么即使列表中不包含B ,也可以从列表中读取B

However, in the code below, cast 2 from List<? extends A> 但是,在下面的代码中,从List<? extends A>强制转换2 List<? extends A> List<? extends A> to List<B> causes a warning. List<? extends A>List<B>会引起警告。 Shouldn't it generate an error for the same reason as before? 它是否应该由于与以前相同的原因而产生错误? In the code, the list only contains one object that is an A but not a B , and yet it is in a list deemed List<B> . 在代码中,列表仅包含一个对象,该对象是A但不包含B ,但它在被视为List<B>

package test;

import java.util.LinkedList;
import java.util.List;

public class TypeLowerBoundCasting {

    static class A {}
    static class B extends A {}

    static void method1() {
        List<A> listOfAs = new LinkedList<A>();
        listOfAs.add(new A());
        // List<B> listOfAsAsListOfBs = (List<B>) listOfAs ; // cast 1: compiler error
        // B b = listOfAsAsListOfBs.get(0); // that would be bad
    }

    static void method2() {
        LinkedList<A> listOfAs = new LinkedList<A>();
        listOfAs.add(new A());
        List<? extends A> listOfAExtensions = listOfAs;
        List<B> listOfAsAsListOfBs = (List<B>) listOfAExtensions; // cast 2: warning, but compiles
        B b = listOfAsAsListOfBs.get(0); // that IS bad; causes a run-time error.
    }

    public static void main(String[] args) {
        method2();
    }
}

A List<? extends A> List<? extends A> List<? extends A> might be a List<B> , so you can cast: List<? extends A> 可能List<B> ,所以可以强制转换:

List<? extends A> list = new ArrayList<B>(); // lose type information
List<B> result = (List<B>) list; // regain type information

Similar to how you can do: 与您的操作类似:

Object o = "Hello World!"; // lose type information
String s = (String) o; // regain type information

Unfortunately, the first cast is unchecked. 不幸的是,第一次演员表是未经检查的。 But a cast in that place is still a valid option, as you can see. 但是,如您所见,在该位置进行强制转换仍然是有效的选择。


But a List<A> can never actually be a List<B> (unless you abuse raw types), because List<A> is not assignable from a List<B> (ie List<B> does not 'extend' List<A> ) so you can't cast: 但是List<A>实际上不能永远是List<B> (除非您滥用原始类型),因为不能从List<B>分配List<A> (即List<B>不会“扩展” List<A> ),因此您不能进行以下转换:

List<A> list = new ArrayList<B>(); // Only works with: (List<A>) (List) new ArrayList<B>();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java从List转换<B>为List <A>,其中B扩展为A.</a> - java cast from List<B> to List<A> where B extends A <A><B>当B扩展A时,</a>从列表转换<A>为列表</a> - Cast from List<A> to List<B> when B extends A 新列表<A & ? extends B>();</a> - new List<A & ? extends B>(); 带通配符的泛型(地图 <? extends A, List<? extends B> &gt;) - Generics with Wildcards (Map<? extends A, List<? extends B>>) 为什么我们不能将 List 转换<A>为 List</a> - Why we can't cast List<A> to List<B> 如果A扩展B扩展C,为什么我可以转换为A但是得到一个ClassCastException转换为C? - If A extends B extends C, why can I cast to A but get a ClassCastException casting to C? 如何投射List <? extends Foo> 列表 <Foo> - How to cast List<? extends Foo> to List<Foo> 添加(列表<!--? extends Z--> ) 其中 Z 是一个接口。 Class B 扩展 A 实现 Z 为什么我们不能用 List 调用 add()<a></a> - add (List<? extends Z>) where Z is an interface . Class B extends A implements Z why cant we call add() with a List<A> 在列表上使用addAll() <? extends E> a和b不起作用 - Using addAll() on List<? extends E> a and b doesn't work JLS 的哪一部分指定您不能从 List 投射<!--? extends List<Superclass--> &gt; 列出<list<subclass> &gt;? </list<subclass> - Which part of the JLS specifies that you can't cast from List<? extends List<Superclass>> to List<List<Subclass>>?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM