public class Test2 {

    public static void main(String[] args) {
        ArrayList<String> list = newArrayList();
        list.add("k");
        list.add("b");
        System.out.println(list.getClass());

        // 这一句编译是不会通过的,因为编译器对pick()返回值的推断是Serializable或Comparable类型
        // 亦即 String "a", list 这两个参数共同继承的接口类型
        // List<String> b = pick("a", list);
        // System.out.println(b);

        // 同样,这里需要声明的变量类型是参数 ("", 1) 共有的父类型即 Serializable或者 Comparable
        Serializable s = pick("", 1);
        System.out.println(s.getClass());

        // 当两个参数类型相同时,则可以正确推断出返回值类型
        String s2 = pick("a", "b");
        System.out.println(s2.getClass());

        // 假如你使用的方法是pick2(E, T)则可以更具参数精确推断出返回值类型
        String s3 = pick2(1.5, "abc");
        System.out.println(s3.getClass());

        // Java 1.6 暂时不支持菱形操作符
        // List<String> list2 = new ArrayList<>();
    }

    static <T> ArrayList<T> newArrayList() {
        return new ArrayList<T>();
    }

    /**
     * a, b 同类型的推断
     *
     * @param a
     * @param b
     * @param <T>
     * @return
     */
    static <T> T pick(T a, T b) {
        return b;
    }

    /**
     * a, b不同类型时的精确推断
     *
     * @param a
     * @param b
     * @param <T>
     * @param <E>
     * @return
     */
    static <T, E> E pick2(T a, E b) {
        return b;
    }
}

 

posted on 2013-09-13 01:49  ZimZz  阅读(4063)  评论(0编辑  收藏  举报