示例:
void process(Consumer<Number> consumer);
应替换为:
void process(Consumer<? super Number> consumer);
此方法签名更灵活,因为它接受更多类型:不仅是 Consumer<Number>
,还有 Consumer<Object>
。
同样,在协变位置键入参数:
T produce(Producer<T> p);
应替换为:
T produce(Producer<? extends T> p);
引用 Effective Java 第三版中的 Joshua Bloch:
第 31 项:使用有界通配符增加 API 灵活性
在 API 中使用通配符类型虽然麻烦,但会使 API 更加灵活。 如果您编写的库将被广泛使用,则应强制正确使用通配符类型。 记住基本规则:生产者-extends, 消费者-super (PECS)。 还要记住,所有 Comparable 和 Comparator 都是消费者。
使用检查选项来切换以下各项的报告:
不变类。 一个不变类的示例是 java.util.List<T>
,因为它既接受值(通过 List.add(T)
方法)又生成值(通过 T List.get()
方法)。
另一方面,contravariant
类只接收值,例如,只有方法 accept(T)
的 java.util.function.Consumer<T>
。 类似地,covariant
类只产生值,例如,只有方法 T get()
的 java.util.function.Supplier<T>
。
人们经常在协变/逆变类中使用有界通配符,但避免在不变类中使用通配符,例如 void process(List<? extends T> l)
。
禁用此选项来忽略此类不变类并保留它们的严格类型,例如 void process(List<T> l)
。
可视为不属于 public API 一部分的 private
方法
实例方法