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; } }