Java泛型(3)泛型的限定

1.官方文档

https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html

2.不可构造泛型形参对象

2.1 限制

public static <E> void append(List<E> list) {
    E elem = new E();  // compile-time error
    list.add(elem);
}

2.2 补偿方法

可以通过反射构造泛型形参对象.

public static <E> void append(List<E> list, Class<E> cls) throws Exception {
    E elem = cls.newInstance();   // OK
    list.add(elem);
}
public static void test(){
    List<String> ls = new ArrayList<>();
    append(ls, String.class);   
}

3.基本类型不可作泛型形参

Pair<int, char> p = new Pair<>(8, 'a');  // compile-time error

4.泛型形参不能声明成static

public class MobileDevice<T> {
    private static T os;

    // ...
}

原因是无法确定os具体是什么类型,可能是Smartphone,Pager,TabletPC中的一种.

    MobileDevice<Smartphone> phone = new MobileDevice<>();
    MobileDevice<Pager> pager = new MobileDevice<>();
    MobileDevice<TabletPC> pc = new MobileDevice<>();

5.参数化类型无法使用 instanceof运算符和强转

5.1 无法用instanceof具体类型

    public static <E> void rtti(List<E> list) {
        if (list instanceof ArrayList<Integer>) {  // compile-time error
            // ...
        }
    }

5.2 可以instanceof  ?通配符

    public static void rtti(List<?> list) {
        if (list instanceof ArrayList<?>) {  // OK; instanceof requires a reifiable type
            // ...
        }
    }

6.未限定泛型实参时,类型强传时有限制

6.1 泛型类型相同,泛型实参为父子,不可

    List<Integer> li = new ArrayList<>();
    List<Number>  ln = (List<Number>) li;  // compile-time error

6.2 泛型类型为父子,泛型实参相同,可以

    List<String> l1 = ...;
    ArrayList<String> l2 = (ArrayList<String>)l1;  // OK

7.参数化类型不可为数组

List<Integer>[] arrayOfLists = new List<Integer>[2];  // compile-time error

8.参数化类型不能当异常类型

8.1 不可直接继承Excetpion、Throwable

// Extends Throwable indirectly
class MathException<T> extends Exception { /* ... */ }    // compile-time error

// Extends Throwable directly
class QueueFullException<T> extends Throwable { /* ... */ // compile-time error

8.2 泛型形参不用作catch语句

public static <T extends Exception, J> void execute(List<J> jobs) {
    try {
        for (J job : jobs)
            // ...
    } catch (T e) {   // compile-time error
        // ...
    }
}

8.3 泛型形参可 extends Exception

class Parser<T extends Exception> {
    public void parse(File file) throws T {     // OK
        // ...
    }
}

9.参数化类型不参与函数重载

public class Example {
    public void print(Set<String> strSet) { }
    public void print(Set<Integer> intSet) { }
}

这两个函数不算重载,它们被擦除后生成相同的函数public void print(Object strSet)。所以编译失败。

 

posted @ 2015-07-25 18:48  f9q  阅读(375)  评论(0)    收藏  举报