List<? super T>和之间有什么区别List<? extends T>?
我曾经使用List<? extends T>,但它不允许我添加元素list.add(e),而List<? super T>它.
我在阅读泛型时遇到了PECS(制片extends人和消费者的super简称).
能否给我一个人解释如何使用佩奇之间解决困惑extends和super?
为什么我super只能使用通配符而不使用类型参数?
例如,在Collection界面中,为什么toArray方法不是这样写的
interface Collection<T>{
<S super T> S[] toArray(S[] a);
}
Run Code Online (Sandbox Code Playgroud) 我有课A,B,C和D那里B延伸A,C扩展A和D延伸A.
我有以下ArrayList几个,其中包含一些元素:
ArrayList<B> b;
ArrayList<? extends A> mix = b;
Run Code Online (Sandbox Code Playgroud)
我打算让变量mix包含类型的元素B,C或D.我试图类型的元素加入C到mix这样的:
mix.add(anElementOfTypeC);
Run Code Online (Sandbox Code Playgroud)
但IDE不允许我这样做,它说:
通过调用转换的方法,无法将anElementOfTypeC转换为CAP#1,其中CAP#1是一个新的类型变量:CAP#1从捕获?延伸A.
我使用<? extends A>得当吗?我该如何解决这个问题?
众所周知,arraylist init.应该是这样的
ArrayList<A> a = new ArrayList<A>();
ArrayList<Integer> a = new ArrayList<Number>(); // compile-time error
Run Code Online (Sandbox Code Playgroud)
所以,为什么java允许这些?
1. ArrayList<? extends Object> a1 = new ArrayList<Object>();
2. ArrayList<?> a2 = new ArrayList<Integer>();
Run Code Online (Sandbox Code Playgroud)
那么,如果他们是正确的,为什么不允许这些呢?
1. a1.add(3);
2. a2.add(3);
Run Code Online (Sandbox Code Playgroud)
编译器消息是:类型ArrayList中的方法add(int,capture#1-of?extends Object)不适用于参数(int)
更一般
1. a1.add(null e);
2. a2.add(? e);
Run Code Online (Sandbox Code Playgroud)
我读到了这个,但很高兴收到你的来信.谢谢
另一个有趣的观点是:
ArrayList<ArrayList<?>> a = new ArrayList<ArrayList<?>>(); // correct
ArrayList<?> a = new ArrayList<?>(); // wrong. I know it's reason but I have some
question in my mind that mentioned above
Run Code Online (Sandbox Code Playgroud) 这是我的计划.我不知道为什么我会收到编译时错误.
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List< ? extends Number > list = new ArrayList<Integer>();
list.add(6); // Compile Time Error
System.out.println(list);
}
}
Run Code Online (Sandbox Code Playgroud)
但是以下程序运行正常
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List< ? super Number > list = new ArrayList<Number>();
list.add(6);
System.out.println(list);
}
}
Run Code Online (Sandbox Code Playgroud)
Eclipse出错:
以下是Eclipse的错误描述:
类型List中的方法add(int,capture#1-of?extends Number)不适用于参数(int)
我理解通用和铸造,但我不懂通用铸造.我以为我只能通过继承树向上或向下投射特定类型,但这证明我错了:
ArrayList<?> cislo = (ArrayList<? extends Number>) new ArrayList<Integer>();
Run Code Online (Sandbox Code Playgroud)
这可能不是最好的例子,但希望你能得到我的观点.这是如何运作的?它的演员类型是什么?
这么奇怪!请先查看代码:
public class A {}
public class B extends A {}
public class C extends A {}
public class TestMain {
public <T extends A> void test(T a, T b) {}
public <T extends A> void test(List<T> a, List<T> b) {}
public void test1(List<? extends A> a, List<? extends A> b) {}
public static void main(String[] args) {
new TestMain().test(new B(), new C());
new TestMain().test(new ArrayList<C>(), new ArrayList<C>());
new TestMain().test(new ArrayList<B>(), new ArrayList<C>());
new TestMain().test1(new ArrayList<B>(), new ArrayList<C>());
}
} …Run Code Online (Sandbox Code Playgroud) 错误:
The method add(capture#1-of ?) in the type List<capture#1-of ?> is not
applicable for the arguments (String)
Run Code Online (Sandbox Code Playgroud)
码:
List<?> to = new ArrayList<Object>();
to.add(new String("here"));
Run Code Online (Sandbox Code Playgroud)
既然List<?>是泛型类型List,因此可以是任何类型,那么为什么它不接受添加方法中的String?
为什么第一个方法编译,第二个方法不编译?for Set和for的泛型ImmutableSet.Builder相同,其add方法的类型签名也相同.
import java.util.Set;
import java.util.HashSet;
import com.google.common.collect.ImmutableSet;
public class F {
public static ImmutableSet<? extends Number> testImmutableSetBuilder() {
ImmutableSet.Builder<? extends Number> builder = ImmutableSet.builder();
Number n = Integer.valueOf(4);
builder.add(n);
return builder.build();
}
public static Set<? extends Number> testJavaSet() {
Set<? extends Number> builder = new HashSet<Number>();
Number n = Integer.valueOf(4);
builder.add(n);
return builder;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用javac版本1.7.0_25来构建.我在第二种方法上得到以下错误,但在第一种方法上没有.我相信我应该在两种情况下都得到错误,因为将Number一个集合放入集合中的类型不正确? extends Number.
error: no suitable method found for add(Number)
builder.add(n);
^
method Set.add(CAP#1) is …Run Code Online (Sandbox Code Playgroud)