泛型通配符:将超类对象分配给子类对象列表 [英] Generics Wildcards: Assigning Super class object to a Subclass object list

查看:131
本文介绍了泛型通配符:将超类对象分配给子类对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Question_1

  class A {} 
class B extends A {}

a aObj = new A();
B bObj = new B();

我们知道下面的例子会在运行时导致类转换异常。 / p>

 列表< B> list_B = new ArrayList< B>(); 
list_B.add((B)aObj); // ClassCast异常

但是

 列表与LT ;?延伸A> list_4__A_AND_SubClass_A = new ArrayList< B>(); 
列表< A> list_A =(ArrayList< A>)list_4__A_AND_SubClass_A;
list_A.add(aObj); //这里没有例外,为什么?

Question_2



在下面的方法中

  void method(List< ;? extends A> list_4__A_AND_SubClass_A){
// How我发现通过的名单是类型A或B?
//决定列表< A> list_A =(ArrayList< A>)list_4__A_AND_SubClass_A;
// OR列表< B> list_B =(ArrayList< B>)list_4__A_AND_SubClass_A;

$ / code>






UPDATE



Q_1
b

最好避免引用下面的集合修改;除非我们确信通过的清单是A / B类型;以保持该列表上的完整性。

 列表< A> list_A =(ArrayList< A>)list_4__A_AND_SubClass_A; 

Q_2



我认为我们可以从调用方法传递一个参数到调用方法,以在调用方法中修改时保持列表的完整性。

  void method(List <?extends A> list_4__A_AND_SubClass_A,Class<?extends A> obj){
if(A.class.isAssignableFrom(obj)){
List< A> list_A =(List< A>)list_4__A_AND_SubClass_A;
list_A.add(new A());
list_A.add(new B());
} else if(B.class.isAssignableFrom(obj)){
List< B> list_B =(List )list_4__A_AND_SubClass_A;
//list_B.add(new A()); //只有我们可以添加B
list_B.add(new B());


$ / code>


解决方案

line:

 列表< A> list_A =(ArrayList< A>)list_4__A_AND_SubClass_A; 

生成'unchecked'警告,因为您可能(并且实际上)只投射一个仅包含 Bs 添加到可以包含 Bs As (记住,因为B是A的一个子类,所以它是 A ),所以下一行

  list_A.add(aObj); 

完全可以,因为您没有注意到警告。



通常,对于泛型, List< ?扩展A> 并不总是与 List< A>



相同回答问题2.

不幸的是,所有的泛型都在编译时被检查,并且在运行时没有太多的信息可用,所以在运行时,你只有一个对象列表,并且不能有效地测试哪种类型的列表是。这个功能是在Java 1.5中引入的后向兼容性和泛型之间的权衡。


Question_1

class A {}
class B extends A {}

A aObj = new A();
B bObj = new B();

We know that below will result in class cast exception at runtime .

List<B> list_B = new ArrayList<B>();
list_B.add((B)aObj); //ClassCast exception

But

List<? extends A> list_4__A_AND_SubClass_A = new ArrayList<B>();
List<A> list_A = (ArrayList<A>)list_4__A_AND_SubClass_A;
list_A.add(aObj); // No exception here, Why?

Question_2

In a method like below

void method(List<? extends A> list_4__A_AND_SubClass_A){
   //How do i find the passed list is of Type A or B ??
   // To decide List<A> list_A = (ArrayList<A>)list_4__A_AND_SubClass_A;
   //        OR List<B> list_B = (ArrayList<B>)list_4__A_AND_SubClass_A;
}


UPDATE

Q_1

Better I should avoid referencing the collection like below for modification; Unless We are very sure about the passed list is type of A/B; to maintain the integrity on that list.

 List<A> list_A = (ArrayList<A>)list_4__A_AND_SubClass_A; 

Q_2

I think we can pass one more argument from the caller method to the calling method to maintain the integrity over the list while modification at calling method.

void method(List<? extends A> list_4__A_AND_SubClass_A, Class<? extends A> obj){
     if (A.class.isAssignableFrom(obj)) {
         List<A> list_A = (List<A>)list_4__A_AND_SubClass_A;
            list_A.add(new A());
            list_A.add(new B());
     } else if (B.class.isAssignableFrom(obj)){
         List<B> list_B = (List<B>)list_4__A_AND_SubClass_A;
            //list_B.add(new A()); //only we can add B
            list_B.add(new B());
     }
}

解决方案

This line:

List<A> list_A = (ArrayList<A>)list_4__A_AND_SubClass_A;

Produces the 'unchecked' warning, because you may ( and indeed are ) casting a list that contains only Bs to a list that can contain Bs or As (Remember, because B is a subclass of A, it IS A), so the next line

list_A.add(aObj);

is perfectly OK, because you did not pay attention to a warning.

In general, with generics, List< ? extends A> is not always the same as List<A>.

To answer question 2.
Unfortunately, all generics are checked at compile time and not much information is available at runtime, so at runtime, you only have a list of objects, and cannot effectively test what kind of list that is. This "feature" was a trade off between backward compatibility and generics when they were introduced in Java 1.5.

这篇关于泛型通配符:将超类对象分配给子类对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆