繁体   English   中英

为什么将ArrayList的泛型转换为超类不起作用?

[英]Why does casting an ArrayList 's generic to a superclass not work?

有人可以向我解释为什么标记为//this line gives a compile error (why?)在下面的代码示例中不起作用?

import java.util.ArrayList;

public class GenericCastCheck {

    class A{
    }

    class B extends A{
    }

    public static void main(String[] args) {

        A aObject = new A();
        B bObject = new B();

        //this line works fine
        aObject = bObject;
        //this line gives a compile (expected)
        bObject = aObject;

        ArrayList<A> aList = new ArrayList<A>();
        ArrayList<B> bList = new ArrayList<B>();

        //this line gives a compile error (why?)
        aList = bList;
        //this line gives a compile error (expected)
        bList = aList;
    }
}

具体来说,当我们说bList的类型为ArrayList<B> ,是否并不意味着它的每个元素都是B的实例? 如果是这样,那么它是什么铸造的问题ArrayList<A> ,如果我们都可以投射单个实例BA

谢谢。

问题是这样的:

ArrayList<A> aList = new ArrayList<A>();
ArrayList<B> bList = new ArrayList<B>();
aList = bList; // if this were valid...
aList.add(new A()); // ...what should happen here?
B b = bList.get(0); // ...and here?

如果对数组执行相同的操作,则会在运行时在第4行中获得ArrayStoreException。 对于通用集合,决定在编译时阻止这种事情。

因为通用是严格的。 他们不是共同的

ArrayList<A> aList只能引用类型AArrayList


来自维基

与数组不同,泛型类既不是协变的也不是逆变的。 例如, List<String>List<Object>都不是另一个的子类型:

 // a is a single-element List of String List<String> a = new ArrayList<String>(); a.add("foo"); // b is a List of Object List<Object> b = a; // This is a compile-time error 

但是,泛型类型参数可以包含通配符(仅使用一次的额外类型参数的快捷方式)。 示例:由于需要对任何对象的列表进行操作的方法,因此可以对对象执行的唯一操作是可以保证类型关系安全的操作。

 // a is a single-element List of String List<String> a = new ArrayList<String>(); a.add("foo"); // b is a List of anything List<?> b = a; // retrieve the first element Object c = b.get(0); // This is legal, because we can guarantee // that the return type "?" is a subtype of Object // Add an Integer to bbadd(new Integer (1)); // This is a compile-time error; // we cannot guarantee that Integer is // a subtype of the parameter type "?" 

通配符也可以绑定,例如分别为上限和下限“ ? extends Foo ”或“ ? super Foo ”。 这允许改进允许的性能。 示例:给出一个List<? extends Foo> List<? extends Foo> ,然后可以检索元素并将其安全地分配给Foo类型(协方差)。 鉴于List<? super Foo> List<? super Foo> ,然后可以安全地添加Foo对象作为元素(逆变)。

的Animesh,

即使B类是A的子类型,ArrayList <B>也不是ArrayList <A>的子类型。 它与B []在同一行上不是A []的子类型。 这是两种独立的不相关类型。

因为在C<A>C<B>之间Java中没有子类型关系,即使AB的超类型,反之亦然。

如果您对Wikipedia中的详细信息查找co / / contra-variance感兴趣。

注意,在Java数组是共变型中,这意味着A[]是的超类型B[]如果A是的超类型B 这就是为什么你有时会得到奇怪的数组转换异常的原因。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM