-
泛型单例工厂
private static final Optional<?> EMPTY = new Optional<>(null); public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; }
-
递归类型限制:
public static <E extends Comparable<E>> E max(Collection<E> c)
第31条 利用有限制通配符来提升API的灵活性
-
List<String>
不是List<Object>
的子类型 -
对于限制通配符
extends
和super
的选择,有PECS表示producer-extends, consumer-super
-
不要用有限制通配符作为函数的返回值(中文版翻译错了,翻译成了通配符)
-
Java引入显示类型参数
public class Union { public static <T> Set<T> union(Set<? extends T> a, Set<? extends T> b) { return Stream.of(a, b) .flatMap(Collection::stream) .collect(Collectors.toSet()); } } public static void main(String[] args) { Set<Integer> integers = Set.of(1, 2, 3); Set<Double> doubles = Set.of(1.0, 2.0, 3.0); Set<Number> result = Union.<Number>union(integers, doubles); }
-
使用时
Comparable
和Comparator
都是消费者,实现时最好是Comparable<? super T>
和Comparator<? super T>
思考
-
开始的时候不大需要考虑太多泛型的扩展,如果当时传入只有一种类型,不需要考虑
extends
或者super
,直接用当时的类就可以,如果后面可能会传入子类或者父类,再扩展 -
其实不用过于纠结泛型的不同限制类型,先动手试一下,如果需要强转等等,再改变泛型的写法。比如之前写过入参和出参相同,是这么写的:
public static <? extends Father> match(List<? extends Father> list) {...} public static test() { List<Son> sons = match(List.of(new Son())).stream() .map(e -> (Son) e) .collect(Collectors.toList()); }
后来发现这么写肯定是有问题的,就改成了这样
public static <T> match(List<T extends Father> list) {...} public static test() { List<Son> sons = match(List.of(new Son())); }
感觉泛型就像正则表达式一样,多试试就行了,不会的时候百度下
网友评论