java的List的原理以及使用

一,java的List的原理以及使用

1》Java的泛型是伪泛型。在编译期间,所有的泛型信息都会被擦除掉。正确理解泛型概念的首要前提是理解类型擦出(type erasure)。

2》Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会在编译器在编译的时候去掉。这个过程就称为类型擦除。

3》如在代码中定义的List<object>和List<String>等类型,在编译后都会编程List。JVM看到的只是List,而由泛型附加的类型信息对JVM来说是不可见的。Java编译器会在编译时尽可能的发现可能出错的地方,但是仍然无法避免在运行时刻出现类型转换异常的情况。类型擦除也是Java的泛型实现方法与C++模版机制实现方式(后面介绍)之间的重要区别。

4》原始类型(raw type)就是擦除去了泛型信息,最后在字节码中的类型变量的真正类型。无论何时定义一个泛型类型,相应的原始类型都会被自动地提供。类型变量被擦除(crased),并使用其限定类型(无限定的变量用Object)替换

二,我们用代码解释下

1》Java的List的默认类型

        List list = new ArrayList();
        list.add(1);
        list.add("1");
        list.add(1.236);

这个编译是不报错的,所以可得默认类型是object


2》Java为什么是伪泛型

        List<Integer> list = new ArrayList<>();
        //使用反射获取list的add方法
        Method method = list.getClass().getMethod("add", Object.class);
        //如果使用Integer去反射获取方法是提示找不到的(错误提示:java.util.ArrayList.add(java.lang.Integer)),证明在编译后的类型是object
        //Method method = list.getClass().getMethod("add", Integer.class);
        //将这个字符串添加进入list集合中,而反射可以在Integer中加入String类型的值,所以也证明类型是object
        method.invoke(list, "Java反射机制实例。");
        //打印出list中的数据,只有一条,因为我们只添加了一条
        System.out.println(list.get(0));

错误如下图,代码

Method method = list.getClass().getMethod("add", Integer.class);

 三,泛型的高级用法

abstract class TestAbstract<T> {

    public T say(T t) {
        return t;
    }

    public abstract T testOne();

    public T testTwo(T t) {
        return t;
    }
}

class TestOne extends TestAbstract<String> {

    @Override
    public String testOne() {
        return "testOne";
    }

    public String testTwo() {
        return super.testTwo("testTwo");
    }
}

使用

        TestOne test = new TestOne();
        String d = test.say("333");
        String d1 = test.testOne();
        String d2 = test.testTwo();    

 

posted @ 2021-07-27 10:41  叶丶梓轩  阅读(648)  评论(0编辑  收藏  举报