读书笔记——《Java核心技术卷一》——泛型(三)

泛型的约束与局限性

一、不能用基本类型实例化类型参数

不能用类型参数替代基本类型。没有Paris<double>,只有,Pair<Double>。原因是类型擦除后,数据域的类型是Object,但是Object不能double类型的值。当不能用Double之类的包装器时,可以使用独立的类和方法来处理。

二、运行时类型查询只实用于原始类型

虚拟机中的对象只属于一个非泛型类型,所以类型查询时查到的结果是类型擦除后的原始类型,例如:

if(a instanceof Pair<String>) //结果为真, 类型是Pair

if(a instanceof Pair<T>)//结果也为真,类型是Pair

//强制类型转换
Pair<String> p = (Pair<String>) a;//会产生一个编译器警告,会转为原始类型Pair


//getClass()返回原始类型

Pair<String> stringPair =  ...;
Pair<Employee> employeePair = ...;
if(stirngPair.getClass() == employeePair.getClass())//结果为真

三、不能抛出也不能捕获泛型实例

不能抛出也不能捕获泛型实例,泛型类继承Throwable都不合法。

public class Problem<T> extends Exception {...}



//不能再catch子句中使用类型变量,
public static <T extends Throwable> void doWork(Class <T> t){

    try
    {
        do work
    }
    catch(T e)
    {
        Logger.glogal.info(...)
    }
}


//异常申明中可以使用类型变量

public static <T extends Throwable> void doWork(T t) throws T {//OK
    try
    {
        do work
    }
    catch(Throwable realCause)
    {
        t,initCause(realCause)
        throw t;
    }
}

四、参数类型化的数组不合法

不能声明这样的数组:

Pair <String>[] table = new Pair<String>[10];

错误类型的元素存入数组时会导致类型错误,但是类型擦除使得在存入错误类型的元素时,可以通过数组存储的检测,但是仍然会导致类型错误而,使得错误检查机制效率降低。

五、不能实例化类型变量

new T(...)和T.class是非法的。类型擦除会使得调用了new Object();

六、泛型类的静态上下文中类型变量无效

public class Singleton<T>
{
    private static String singleInstance;//这样写是错误的

    //这个方法也是错的
    public static String getSingleInstance (){
        if(singleInstance != null) return singleInstance;
    }
}

七、注意擦除后的冲突

猜你喜欢

转载自blog.csdn.net/let4897/article/details/82355977