java泛型与数组

泛型与数组

概述:

首先java中数组是不支持泛型的,对于数组不支持泛型的原因,也有很多回答。这里有两个我认为比较好的回答,供大家参考泛型不支持数组的分析泛型为什么不支持数组。以上两个回答还是比较深入,和透彻的。
我对于该问题的理解是:由于泛型只是在编译的时候,起到类型检测,及类型转换字节码的生成,也就是说具有泛型的java文件,最终生成的字节码会将泛型信息抹去,具体数据的引用类型一般都用object的来替代。并在对应的位置加上了类型转换代码。
例子1:
HelloWorld.java

public class HelloWorld{

    public static void main(String args[]){
        User<String> user = new User<String>();
        user.setValue("weiwei");
        System.out.println(user.getValue());

    }

}

User.java

public class User<T> {

    private T value;

    public void setValue(T value){
        this.value = value;
    }

    public T getValue(){
        return value;
    }

}

执行命令 javac 和 javap -c命令得到class字节码结果如下:
这里写图片描述

由上图第11 18 21行可知,编译过后11行数据类型为object类型 18行数据为object 类型21行为数据强转语句(String)object。

例子2:

public static void testRunGenerics(){
        List<String> list1 = new ArrayList<String>();
        List<Long> list2 = new ArrayList<Long>();

    System.out.println(list1.getClass().equals(list2.getClass()));

    }

以上代码运行结果为true。也就是说无论List还是List在运行期间都是类型List。

而java中规定数组在实例化的时候,需要确切的知道存放数据的类型(这样更方便的操作使用数组)。也就是说假设数组支持泛型,那么在编译成字节码的时候对于T[] = new T[10];最终会编译成Object[] objects=new Object[10],也就是说数组的具体类型在运行期间为object 类型,这时候对于数组内的元素操作可以强转也可以正常使用。但是编译器生成字节码的时候也有可能生成 (String[])(Objects) 这样的强转代码(出现转换错误)。

包装类实现泛型数组:

例子1 利用object数组间接实现泛型数组:

GenericArray.java 文件

package generics;

public class GenericArray<T> {
    private Object[] values;

    public GenericArray(int count){

        values = new Object[count];

    }

    public void setValue(T t,int position){

        values[position] = t;
    }

    public T getValue(int position){

        return (T)values[position];
    }

    //注意此句代码调用会出错
    public T[] getValues(){

        return (T[])values;
    }

}

测试代码:

public class Test {

    public static void main(String[] args) {

        GenericArray<String> generic=new GenericArray(10);

        generic.setValue("wenwei1", 0);
        generic.setValue("wenwei2", 1);

        System.out.println(generic.getValue(0));
        System.out.println(generic.getValue(1));
        //
        String[]content = generic.getValues();
        }
    }

执行结果:
这里写图片描述
分析:上面代码可以编译通过,而且我们使用GenericArray存储数据可以正常使用,但当我们调用其getValues则会出现强转类型错误(这种错误就是我们在概述中分析的编译器生成强转代码造成的)
列子2 利用类型标识间接实现泛型数组:

GenericArray1.java文件

public class GenericArray1 <T>{
    private T[] values;

    public GenericArray1(Class<T> type,int length){
        values= (T[])Array.newInstance(type, length);
    }

    public void setValue(T t,int position){

        values[position] = t;
    }

    public T getValue(int position){

        return (T)values[position];
    }

    public T[] getValues(){

        return values;
    }


}

测试代码:

public class Test {

    public static void main(String[] args) {

        GenericArray1<String> generic=new GenericArray1<String>(String.class,10);

        generic.setValue("wenwei1", 0);
        generic.setValue("wenwei2", 1);

        System.out.println(generic.getValue(0));
        System.out.println(generic.getValue(1));

        String[]content = generic.getValues();
        System.out.println(content[0]);
        }
    }   

运行结果:
这里写图片描述
分析:上面代码可以编译通过,我们使用GenericArray存储数据可以正常使用,而且调用其getValues也不会出现强转类型错误,这种方式比较推荐(因为我们调用Array.newInstance()生成的数组是String[]类型的数组)

补充说明:对于泛型数组,最简单的我们可以利用容器List来模拟实现!

希望对您有所帮助!

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值