为什么<?扩展Number>不适用于Integer?

8 java generics java-8

为什么

Predicate<? super Integer> isGreaterThanZero = num -> num.intValue() > 0;
Run Code Online (Sandbox Code Playgroud)

效劳于

isGreaterThanZero.test( new Integer( 2 ));
Run Code Online (Sandbox Code Playgroud)

并不是

Predicate<? extends Number> isGreaterThanZero = num -> num.intValue() > 0;
Run Code Online (Sandbox Code Playgroud)

我认为它们是相同的,因为它Integer 是-a Number

Mis*_*sha 13

当您声明时Predicate<? extends Number> isGreaterThanZero,您告诉编译器isGreaterThanZeroPredicate由某个未知子类型参数化的Number.

就编译器而言,它可以是a Predicate<Double>或a Predicate<BigInteger>.你能安全地Integer去往test(Double x)或去test(BigInteger x)吗?你不能.唯一可以安全传递给test方法的Predicate<? extends Number>null.

如果你想isGreaterThanZero成为一个适用于任何子类型的谓词Number,你应该声明它Predicate<Number>.

  • 它适用于`super`,因为`Integer`是任何满足通配符`的类的子类型?超级号码.所以无论通配符恰好代表什么类,`Predicate <?super Number>`can*consume*an`Engger`.您可能需要阅读http://stackoverflow.com/q/2723397/3920048,以深入解释这些问题和*PECS*助记符. (3认同)
  • @fireflieslive对于你的第二个问题,不,如果只有一个`Number`子类型,编译器就不会让你这样做.如果你编译你的代码并且明天写一个新的`Number`子类怎么办?现在您的编译代码不是类型安全的. (3认同)