zoukankan      html  css  js  c++  java
  • Effective Java 28 Use bounded wildcards to increase API flexibility

    Get and Put Principle

    PECS stands for producer-extends(? extends T), consumer-super(? super T).

    1. For maximum flexibility, use wildcard types on input parameters that represent producers or consumers.

       

    // Wildcard type for parameter that serves as an E producer

    public void pushAll(Iterable<? extends E> src) {

    for (E e : src)

    push(e);

    }

       

    // Wildcard type for parameter that serves as an E consumer

    public void popAll(Collection<? super E> dst) {

    while (!isEmpty())

    dst.add(pop());

    }

       

    Although lists can both consume and produce values, the reduce method uses its list parameter only as an E producer, so its declaration should use a wildcard type that extends E. The parameter f represents a function that both consumes and produces E instances, so a wildcard type would be inappropriate for it. Here's the resulting method declaration:

       

    // Wildcard type for parameter that serves as an E producer

    static <E> E reduce(List<? extends E>list, Function<E> f, E initVal)

       

    2. Do not use wildcard types as return types.

    public static <E> Set<E> union(Set<? extends E> s1, Set<? extends E> s2)

       

    3. If the user of a class has to think about wildcard types, there is probably something wrong with the class's API.

    4. Use explicit parameter for the generic method.

    Set<Integer> integers = ... ;

    Set<Double> doubles = ... ;

    Set<Number> numbers = union(integers, doubles);

    Set<Number> numbers = Union.<Number>union(integers, doubles);

       

    Always use Comparable<? super T> in preference to Comparable<T>.The same is true of comparators, so you should always use Comparator<? super T> in preference to Comparator<T>.

    public static <T extends Comparable<? super T>> T max(List<? extends T> list)

       

    5. If a type parameter appears only once in a method declaration, replace it with a wildcard for its simplify.

    // Two possible declarations for the swap method

    public static <E> void swap(List<E> list, int i, int j);

    public static void swap(List<?> list, int i, int j);

    // Use this one instead of first one. But this one will not compile since the one above cannot set an element

    // to the list object whose type is List<?> unless the object is null.

    // And you should provide clean API list the code below.

       

    public static void swap(List<?> list, int i, int j) {

    swapHelper(list, i, j);

    }

    // Private helper method for wildcard capture

    private static <E> void swapHelper(List<E> list, int i, int j) {

    list.set(i, list.set(j, list.get(i)));

    }

       

    Summary

    Using wildcard types in your APIs, while tricky, makes the APIs far more flexible. If you write a library that will be widely used, the proper use of wildcard types should be considered mandatory. Remember the basic rule: producer-extends, consumer-super(PECS). And remember that all comparables and comparators are consumers.

    作者:小郝
    出处:http://www.cnblogs.com/haokaibo/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    QT5每日一学(五)QT布局管理器
    构造注入链:POP
    Jarvis OJ--PHPINFO
    XCTF(Web_php_unserialize)
    XCTF-反序列化中_wakeup()函数
    session反序列化
    PHP反序列化
    默认安装的phpMyAdmin会存在哪些安全隐患
    如何进行数据库备份
    开启mysql外部访问(root外连)
  • 原文地址:https://www.cnblogs.com/haokaibo/p/use-bounded-wildcards-to-increase-API-flexibility.html
Copyright © 2011-2022 走看看