我在阅读泛型时遇到了PECS(制片extends人和消费者的super简称).
能否给我一个人解释如何使用佩奇之间解决困惑extends和super?
以下程序在Java 7和Eclipse Mars RC2 for Java 8中编译:
import java.util.List;
public class Test {
static final void a(Class<? extends List<?>> type) {
b(newList(type));
}
static final <T> List<T> b(List<T> list) {
return list;
}
static final <L extends List<?>> L newList(Class<L> type) {
try {
return type.newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用javac 1.8.0_45编译器,报告以下编译错误:
Test.java:6: error: method b in class Test cannot be applied to given types;
b(newList(type));
^
required: List<T>
found: CAP#1
reason: inference …Run Code Online (Sandbox Code Playgroud) 我一直想知道Java泛型的一些奇怪方面和通配符的使用.比方说,我有以下API:
public interface X<E> {
E get();
E set(E e);
}
Run Code Online (Sandbox Code Playgroud)
然后,假设我们声明了以下方法:
public class Foo {
public void foo(X<?> x) {
// This does not compile:
x.set(x.get());
}
public <T> void bar(X<T> x) {
// This compiles:
x.set(x.get());
}
}
Run Code Online (Sandbox Code Playgroud)
从我的"直觉"的理解,X<?>实际上是一样的X<T>,只是未知<T>是正式未知的客户端代码.但在内部foo(),我猜测编译器可以推断(伪JLS代码)<T0> := <?>[0], <T1> := <?>[1], etc....这是大多数程序员明确而直观地做的事情.他们委托私人助手方法,导致许多无用的锅炉板代码:
public class Foo {
public void foo(X<?> x) {
foo0(x);
}
private <T> void foo0(X<T> x) {
x.set(x.get());
}
}
Run Code Online (Sandbox Code Playgroud)
另一个例子: …