【发布时间】:2016-07-30 21:56:45
【问题描述】:
PECS 原则是关于您在函数中选择哪种类型的参数,具体取决于您将如何使用该参数。
我的问题是,一旦您选择使用super(因为您的函数可能是消费者),您就不能将某些泛型类实例传递给该函数。
让我们考虑以下程序:
public class Main{
public static void main(String[] args){
List<?> unbound = new ArrayList<Long>();
List<? extends Long> extendsBound = new ArrayList<Long>();
List<? super Long> superBound = new ArrayList<Long>();
takeExtend(unbound);
takeExtend(extendsBound);
takeExtend(superBound);
takeSuper(unbound);
takeSuper(extendsBound);
takeSuper(superBound);
}
static <T> void takeExtend(List<? extends T> l){}
static <T> void takeSuper(List<? super T> l){}
}
编译器给出以下错误:
error: method takeSuper in class Main cannot be applied to given
types;
takeSuper(unbound);
^ required: List<? super T> found: List<CAP#1> reason: cannot infer type-variable(s) T
(argument mismatch; List<CAP#1> cannot be converted to List<? super T>) where T is a type-variable:
T extends Object declared in method <T>takeSuper(List<? super T>) where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
我试图找到一种对称性,例如我们为 PECS 规则提供的对称性,但我没有找到。 所以:
- 为什么不能将
<?>或<? extends T>传递给期望<? super T>的函数? - 为什么可以将
<?>传递给需要<? extends T>的函数? - 为什么可以将
<? super T>传递给需要<? extends T>的函数?
【问题讨论】:
-
我已经掌握了PECS原理,但这个问题是关于他在不同种类的仿制药中的应用。
-
抱歉,在评论之前我没有仔细阅读您的问题。我删除了我的评论;我同意这不一样。
-
你的 Java 版本是多少?这适用于 Java 8 及更高版本。
-
我使用的是 Java 1.8.0_60,但它不适合我。
-
我有点认为这个编译器错误是一个错误。它应该捕获转换然后推断
T是CAP#1。List<CAP#1>是List<? super CAP#1>所以应该没问题。这是通过在单独的步骤中进行捕获转换的一种解决方法:ideone.com/DBefuU。
标签: java generics extends super