另一个java通用问题 [英] another java generic question
问题描述
interface Able {/ * ... * /}
class A实现Able {/ * ... * /}
我有
地图< String ,?扩展Able>如;
as = new HashMap< String,A>();
为什么会出现以下错误:
as.put(a,new A());
有什么想法?
对java泛型的引用很好( jdk站点)。
确实@Oli_Charlesworth给出了一个很好的答案,但也许这一个会更完整。
在集合中<?如果你有
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>
您可以像这样添加任何你想要的:
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屋!