这段代码
static void writeTo(List<? super Apple> apples) {
apples.add(new Apple());
apples.add(new Jonathan());
}
Run Code Online (Sandbox Code Playgroud)
该代码的作者说明了这一点
参数apples是某种类型的List,它是Apple的基本类型; 因此,您知道添加Apple或Apple的子类型是安全的.由于下限是Apple,
Jonathan是Apple的子类.
但是当我尝试这个时
List<Jonathan> loj = new ArrayList<Jonathan>();
listSuper(loj);
Run Code Online (Sandbox Code Playgroud)
它给了我这个错误
The method listSuper(List<? super Apple>) in the type Basket<T> is not applicable for the arguments (List<Jonathan>)
Run Code Online (Sandbox Code Playgroud)
哪里listSuper是这样的
static void listSuper (List<? super Apple> cont) {}
Run Code Online (Sandbox Code Playgroud)
这两者有何不同?
还有什么让我对我发布的第一个代码感到困惑的是我想到的?super T意味着任何基本类型的T.但是从它的外观上他添加了T的子类型.我很困惑.
我有一个列表包含未来的任务,未来的类型是未知的,所以我创建一个带通配符类型的列表?,但是当我向列表中添加一个元素时,就会发生编译错误.
这是代码:
private List<Pair<String, Future<?>>> futureTasks = Collections.synchronizedList(
new ArrayList<Pair<String, Future<?>>>(8));
// taskId is a string
futureTasks.add(Pair.makePair(taskId, getExecutors().submit(
new Callable<String>() {
public String call() {
try {
return exportAccountSrcTask(tmpFile); // return a string
} catch (Exception e) {
logger.error("failed to export account src", e);
}
return null;
}}))
);
Run Code Online (Sandbox Code Playgroud)
编译错误:
add(Pair<String,Future<?>>)类型中的方法List<Pair<String,Future<?>>>不适用于参数(Pair<String,Future<String>>)
我读到使用带有这样的超级通配符:
public class MyClass <T extends Comparable<? super T>> {
...
}
Run Code Online (Sandbox Code Playgroud)
代替:
public class MyClass <T extends Comparable<T>> {
...
}
Run Code Online (Sandbox Code Playgroud)
可以让这个班级"更通用",但我不明白为什么.
有人能提供一些具体的例子吗?
更改Collections.unmodifiableList为return List<? extends T>而不是List<T>将阻止在编译时添加和删除元素,而不是抛出运行时异常.
是否存在由此替代方案引起的严重问题,从而排除它?
我在列表中使用通配符和下界泛型,但编译器抛出错误.
码:
int intStart = 0;
Number num = new Integer(2);
List<? super Integer> listOfNumbers = new ArrayList<>();
listOfNumbers.add(intStart);
listOfNumbers.add(num); //throws compiler error
Run Code Online (Sandbox Code Playgroud)
错误:
类型List中的方法add(capture#8-of?super Integer)不适用于参数(Number)
有了List<? super Integer>,我应该被允许添加任何类型的对象Integer或其超类型,例如数字或对象.我已经经历了一些SO讨论,但无法找到为什么我应该犯错误.
这不是一个重复的问题,因为我特别询问编译器如何允许将一个Cat添加到List<? super Cat> catListALREADY包含Dog 的集合中.你看到animaList已经包含了Cats and Dogs因为它们是动物但是调用addCat需要List<? super Cat>添加一个新的猫,add(new RedCat());即使该列表已经包含一只狗.难道编译器不允许这样做以便完成List<? super Cat>签名,因为它试图将Cats添加到已经包含Dogs的列表中吗?
然而明确地呼吁
catList.add(new Dog());
Run Code Online (Sandbox Code Playgroud)
强制执行约束.所以问题是为什么行为的差异?
原始问题:我一直在玩Java泛型并注意到一个奇怪的(?)问题.在下面的代码片段中,您可以将Dog和Cat添加到animalList中,然后将此列表传递到addCat(List<? super Cat> catList)
并添加另一个Cat实例.因此,我们有一个包含Dogs和Cats的List,它们覆盖了?超级猫的边界,因为它不应该允许狗?
但是一旦你取消注释了
//catList.add(new Dog());
Run Code Online (Sandbox Code Playgroud)
你得到一个编译时错误
(参数不匹配;狗不能转换为CAP#1)
package com.tutorialspoint;
import java.util.ArrayList;
import java.util.List;
public class GenericsTester {
public static void addCat(List<? super Cat> catList) {
catList.add(new RedCat());
catList.add(new Cat());
//catList.add(new Dog());
System.out.println("Cat Added");
}
public static void main(String[] args) {
List<Animal> animalList= new ArrayList<Animal>();
List<Cat> catList= new ArrayList<Cat>(); …Run Code Online (Sandbox Code Playgroud) 我有两个类,一个超类和一个继承该超类的子类。我想将两个数组列表合并为一个。这两个数组列表具有不同的类型。一个是超类列表,另一个是子类。
这是我的三个列表:
public ArrayList<subClass> list1;
public ArrayList<superClass> list2;
public ArrayList<? extends superClass> combined; // so this accepts all subclasses as well
Run Code Online (Sandbox Code Playgroud)
然后,我试图完成以下任务:
combined.addAll(list1);
combined.addAll(list2);
Run Code Online (Sandbox Code Playgroud)
编译器说:
addAll in arrayList cannot be applied to list1
addAll in arrayList cannot be applied to list2
Run Code Online (Sandbox Code Playgroud)
但是:combined = list1;没有错误。使用等号时,我无法将两个列表合并。
我该如何实现?
我试图在Integer流上使用reduce方法来获取所有值的总和。但出现语法错误,无法找出错误。
List<Integer> ee = new ArrayList<Integer>();
Function<? super Integer, ? extends Integer> f3 = x -> x / 2;
BinaryOperator<? extends Integer> accumulator = (x, y) -> x + y;
ee.stream().map(f3).reduce(new Integer(0), accumulator);
Run Code Online (Sandbox Code Playgroud)
它给出了错误:
The method reduce(capture#2-of ? extends Integer, BinaryOperator<capture#2-of ? extends Integer>) in the type Stream<capture#2-of ? extends Integer> is not applicable for the arguments (Integer, BinaryOperator<capture#7-of ? extends Integer>)
Run Code Online (Sandbox Code Playgroud) 首先,我对这个不太好的标题表示歉意,我是 Java 新手,不知道如何命名它。
我有一个接口类“TestInterface”:
ublic interface TestInterface {
String getForename();
void setForename(String forename);
String getSurname();
void setSurname(String surname);
}
Run Code Online (Sandbox Code Playgroud)
“TestImpl”实现“TestInterface”:
public class TestImpl implements TestInterface{
private String forename;
private String surname;
@Override
public String getForename() {
return forename;
}
public void setForename(String forename) {
this.forename = forename;
}
@Override
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个名为“ExtendTest”的调用,它扩展了“TestImpl”:
public class ExtendTest extends TestImpl{
private String firstLineAddress;
public String getFirstLineAddress() {
return …Run Code Online (Sandbox Code Playgroud) public class Test {
public class A {}
public class B extends A {}
public class C extends B {}
public void testContraVariance(List<? super B> myBlist) {
B b = new B();
C c = new C();
myBlist.add(b);
myBlist.add(c);
A a = myBlist.get(0); // does not compile
}
}
Run Code Online (Sandbox Code Playgroud)
如果 myBlist 接受 B 的超类型,这意味着 B 或 up,那么为什么还可以像中那样向它添加一个子类型myBlist.add(c)?
java ×10
generics ×8
arraylist ×2
collections ×2
super ×2
wildcard ×2
comparable ×1
inheritance ×1
java-8 ×1
java-stream ×1
pecs ×1