另一个java通用问题 [英] another java generic question

查看:100
本文介绍了另一个java通用问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  interface Able {/ * ... * /} 
class A实现Able {/ * ... * /}

我有

 地图< String ,?扩展Able>如; 
as = new HashMap< String,A>();

为什么会出现以下错误:

  as.put(a,new A()); 

有什么想法?

解决方案

对java泛型的引用很好( jdk站点)。

确实@Oli_Charlesworth给出了一个很好的答案,但也许这一个会更完整。



集合中<?如果你有


pre> class A implements Able {...}

  class B implements Able {...} 

然后,收藏<?

 集合< A>扩展Able>  
收藏< B>

因此,写一些如

的语句是合法的

  //代码片段01 
集合< ?扩展Able>列表;
收藏< A> listA的;
收藏< B>数组listB;
list = listA;
list = listB;

这就是为什么通配符符号 Collection <?>的原因。



但是,这里变得更加有趣:

集合< A> 中,只能插入 A (包括子类)的对象。同样适用于集合< B> 。在这两个你不能添加只是 Able 的东西。例如:

  //代码片段02 
listA.add(new A()); //在编译时有效
listA.add(new B()); //在编译时无效
listB.add(new B()); //在编译时有效
listB.add(new A()); //在编译时无效

因此,如果您将代码片段01& 02 ,你会明白编译器绝对不可能接受如下语句:

  Collection< ; ?扩展Able>列表; 
list.add(new A()); //不允许,只有列表为< A>
list.add(new B()); //不允许,仅在列表为< B>时才能使用。

所以,超级类型 Collection< ?扩展Able> 不接受添加任何内容。更通用的类型提供了子类型的功能交集,因此,子类型的功能更少。在这里,我们失去了添加 A 对象和 B 对象的能力。这些特性将在后面的层次结构中发生......甚至意味着我们不能在超类中添加任何内容 Collection< ?扩展Able>



补充说明:

另外, 集合< Able> 您可以像这样添加任何你想要的:

收集和LT;能够>列表;
list.add(new A()); // valid
list.add(new B()); //有效的

但是,集合< Able> 不是集合< A> 集合< B> 的超类。与任何继承关系一样,这意味着子类可以做任何超类可以做的事情,因为继承是专业化的。因此,这意味着我们可以将A对象和B对象添加到两个子类 Collection< A> Collection< B> 而事实并非如此。因为它不是超类,所以你不能拥有:

 集合< Able>列表; 
收藏< A> listA的;
收藏< B>数组listB;
list = listA; //无效,因为没有继承层次结构
list = listB; //无效,因为没有继承层次结构

请注意,继承是一个超级关系(generalization / specialization )和集合定义了一个meronimic关系(容器/集装箱)。把它们两个都正式结合起来是一件令人头疼的事情,尽管人类模糊的生物在某种程度上可以很容易地使用它,例如法国人的形象: synecdocque 。 :)

I have the following class:

interface Able{/* ... */}
class A implements Able{/* ... */}

and I have

Map<String,? extends Able> as;
as = new HashMap<String, A>();

why does the following cause an error:

as.put("a", new A());

Any ideas?

解决方案

The reference to java generics is good (jdk site).

Indeed @Oli_Charlesworth gave a good answer, but maybe this one will be more complete.

In a Collection<? extends Able> you can't insert anything that's right.

If you have

class A implements Able {...}

and

class B implement Able {...}

Then, Collection<? extends Able> is a super type of both :

Collection<A>
Collection<B>

Thus it is legal to write some statement like

//Code snippet 01
Collection< ? extends Able > list;
Collection<A> listA;
Collection<B> listB;
list = listA;
list = listB;

That is indeed the reason why the wildcard notation Collection<? extends Able> exists.

But, here things are getting more interesting :

In a Collection<A> you can only insert objects that are A (including subclasses). Same for Collection<B>. In both you can't add something that is just Able. For instance :

//Code snippet 02
listA.add( new A() );  //valid at compile-time
listA.add( new B() );  //not valid at compile-time
listB.add( new B() );  //valid at compile-time
listB.add( new A() );  //not valid at compile-time

Thus, if you group what we saw in code snippets 01 & 02, you will understand that it's absolutely impossible for the compiler to accept a statement like :

Collection< ? extends Able > list;
list.add( new A() );         //not allowed, will work only if list is List<A>
list.add( new B() );         //not allowed, will work only if list is List<B>

So yes, the super type Collection< ? extends Able > doesn't accept to add anything. More general types offer the intersection of functionalities of subtypes, and, as such, less features that subtype. Here, we lose the ability to add A objects and B objects. Those feature will happen later in the hierarchy... and it even means that we can't add anything in the super class Collection< ? extends Able >

Additional remark :

Also, note that in a Collection<Able> you can add whatever you want like this :

Collection< Able > list;
list.add( new A() );         //valid
list.add( new B() );         //valid

But, Collection<Able> is not a superclass of Collection<A> and Collection<B>. It would mean, as with any inheritance relation, that subclasses can do whatever their superclass can do, as inheritance is specialization. So, this would mean that we could add A objects and B objects to both subclasses Collection<A> and Collection<B> and that is not the case. So as it's not a superclass you can't have :

Collection<Able> list;
Collection<A> listA;
Collection<B> listB;
list = listA;  //not valid because there is no inheritance hierarchy
list = listB;  //not valid because there is no inheritance hierarchy

Note that inheritance is a hyperonimic relation (generalization/specialization) and collections define a meronimic relation (container/containee). And it's a headache to combine both of them formally, even though it's somewhat used quite easily by the fuzzy creatures humans are, for instance in the french figure of speech : synecdocque. :)

这篇关于另一个java通用问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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