我在阅读泛型时遇到了PECS(制片extends人和消费者的super简称).
能否给我一个人解释如何使用佩奇之间解决困惑extends和super?
我有几个关于Java中通用通配符的问题:
List<? extends T>和之间有什么区别List<? super T>?
什么是有界通配符,什么是无界通配符?
我想知道为什么下面的代码不起作用:
Collection <? super String> col = new ArrayList<String>();
col.add(new Object());// does not compile
col.add("yo!");// compiles indeed;
Run Code Online (Sandbox Code Playgroud)
如果类型是<? super String>它可以包含超出String(包括字符串)的任何东西不?
我知道关于这个话题有很多问题,但遗憾的是他们无法帮助我消除我的晦涩.首先,看下面的例子.我不明白,为什么以下"添加"-method someCage.add(rat1)不起作用并以下列异常中止:
线程"main"中的异常java.lang.Error:未解决的编译问题:Cage类型中的方法add(捕获#2-of?extends Animal)不适用于参数(Rat)
这Cage<Rat>是不一样的原因Cage<Animal>吗?如果是,我在这个例子中不理解它,所以我不确定编译器到底做了什么.这是代码示例:
package exe;
import cage.Cage;
import animals.Animal;
import animals.Ape;
import animals.Lion;
import animals.Rat;
public class Main {
public static void main(String[] args) {
Lion lion1 = new Lion(true, 4, "Lion King", 8);
Lion lion2 = new Lion(true, 4, "King of Animals", 9);
Ape ape1 = new Ape(true, 2, "Gimpanse", true);
Ape ape2 = new Ape(true, 2, "Orang Utan", true);
Rat rat1 = new Rat(true, 4, "RatBoy", true);
Rat rat2 = new …Run Code Online (Sandbox Code Playgroud) 假设一个SuperClass America和它的两个SubClasses SouthAmerica和NorthAmerica
情况1
对于数组:
America[] am = new SouthAmerica[10]; //why no compiler error
am[0]= new NorthAmerica(); //ArrayStoreException at RunTime
Run Code Online (Sandbox Code Playgroud)
案例2
在Genrics中:
ArrayList<America> ame = new ArrayList<SouthAmerica>(); //this does not compile
Run Code Online (Sandbox Code Playgroud)
我的问题不是为什么案例2不编译,但我的问题是为什么案例1编译.我的意思是还有什么可以做这个基础数组类型和子数组对象?
在阅读这篇文章时,我被困在这里.我从链接中粘贴了这个.我不明白为什么List<Number>或List<? extends Number>不能在这里使用的推理.
public void doStuff( List<Integer> list ) {
list.add(1);
// do stuff
list.get(0);
}
We can generalize this one step further by generalizing the generic parameter:
public void doStuff( List<? super Integer> list ) {
list.add(1);
// do stuff
list.get(0);
}
Run Code Online (Sandbox Code Playgroud)
有些读者可能会问为什么更直观的List <Number>不能在这里使用.实际上,我们可以尝试将方法定义为采用List <Number>或List <?扩展Number>,但是第一个定义将排除传入实际ArrayList <Integer>的可能性,而第二个定义将禁止add()方法(因为有人可能会传入ArrayList <Float>,并且会找到调用doStuff后,在Floats之间的整数).
几天前我写了一个简单的Java程序,我发现这段代码不起作用(它给出了编译时错误):
ArrayList<Document> docs = new ArrayList<Book>();
Run Code Online (Sandbox Code Playgroud)
其中Document是一个接口,Book实现了Document.
为什么Java中的继承不适用于泛型?如果我希望该代码可以工作,我必须使用通配符,如下所示:
ArrayList<? extends Document> docs = new ArrayList<Book>();
Run Code Online (Sandbox Code Playgroud)
我想知道这是什么原因?如果我需要一个文档的ArrayList,并且我知道Book也是一个Document,为什么我不能使用BooksList of Books作为DocumentList of Documents?