• 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接口。

  • 相关阅读:
    手机维修费杂乱 消协命令设立扶植行业标准
    ImageList控件的使用方法
    三峡实习记之一
    [原创]2天的搜索经验对IIS的问题的全面解决方案
    亲历虚拟机安装Ubuntu Linux系统
    新的一年,新的开始
    VS2003中实现身份验证的探索经验
    [原创]VS2003中ASP.NET实现自定义用户导航控件
    全面控制Windows任务栏
    单刀赴广州
  • 原文地址:https://www.cnblogs.com/csuwater/p/5398853.html
Copyright © 2020-2023  润新知