java泛型II-泛型中存在的约束与局限性

java泛型中存在一定的约束和局限性,这些限制的主要原因是java虚拟机中对泛型的处理机制有关,即类型擦除
1:不能用基本类型实例化类型参数
主要原因就是:类型擦除引起的,ArrayList会被转为Object,但double没有继承object。
如:
ArrayList<Double> list=new ArrayList<>();//正确 ArrayList<double> list=new ArrayList<>();//错误
2:运行时类型查询只适合用于原始类型

public class test2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ArrayList<String> list=new ArrayList<>();
        ArrayList<Integer> list2=new ArrayList<>();
System.out.println(list.getClass()==list2.getClass());
System.out.println(list.getClass().getName());
    }
}

运行结果:

true
java.util.ArrayList

通过运行结果发现:
两次调用的getClass都返回的java.util.ArrayList,因此在泛型中类型查询返回的是泛型的原始类型。
3:不能创建参数化类型的数组

public static void main(String[] args) {
        // TODO Auto-generated method stub
        Pair<String> [] array=new Pair<String>[10];

    }

运行结果:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    Cannot create a generic array of Pair<String>

    at com.csu.fanxing.test2.main(test2.java:9)

结果分析:由于array经过虚拟机擦除后,array类型是Pair[],所以假设改数组能够初始化成功,那存储时依然会出现问题。
4:不能实例化类型变量

public class Pair<T> {
    private T first;
    private T second;
    public T getFirst() {
        return first;
    }
    public Pair()
    {
        first=new T();
        second=null;
    }

报错:first=new T();Cannot instantiate the type T。无法实例化类型T。所以不能用像new T(),new T[...]等这样的表达式实例化类型变量。
5:泛型类的静态上下文中类型变量无效

public class Singleton <T>{
    private static T singleInstance;//错误
    public static T getInstance()//错误
    {
        //dosomething
    }
}

编译不通过的主要原因是泛型擦除后,只有Singleton,如果声明一个Singleton和一个Singleton,那么就会出现程序混乱。因为泛型类中的泛型参数的实例化是在定义对象的时候指定的,而静态变量和静态方法不需要使用对象来调用。对象都没有创建,如何确定这个泛型参数是何种类型,所以当然是错误的。

public static<T> T getInstance(T a)//错误
    {
        //dosomething
    }

注意:这个是正确的,因为它是泛型方法,它使用的T是自己在方法中定义的T,而不是泛型类中的T。
6:类型擦除后的冲突
当泛型类型被擦除后,创建条件不能产生冲突。如果在Pair类中添加下面的equals方法:

class Pair<T>   {
    public boolean equals(T value) {
        return null;
    }   
}

考虑一个Pair。从概念上,它有两个equals方法:

booleanequals(String); //在Pair<T>中定义
boolean equals(Object); //从object中继承

但是,这只是一种错觉。实际上,擦除后方法
boolean equals(T)变成了方法 boolean equals(Object),这与Object.equals方法是冲突的!当然,补救的办法是重新命名引发错误的方法。
7:泛型类型的继承规则
这里写图片描述
从图可以看出,B与BSub之间是集成关系,但在ArrayList与ArrayList没有任何关系。
但是特别注意:ArrayList与List之间有关系,由于ArrayList实现的是List接口。

转载于:https://www.cnblogs.com/csuwater/p/5398853.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值