Java 为什么不能创建泛型数组?

版权声明:该博客为博主原创,转载请标明出处! https://blog.csdn.net/DJH2717/article/details/82824635

泛型是 JDK 1.5 中引入的新特性, 首先我们来思考下 java 为什么要引入泛型, 我们看如下代码:

        List list = new ArrayList();
        list.add(55);
        list.add("dd");
        System.out.println(((Integer) list.get(1)) - 5);

这段代码在编译器是没有任何问题的, 可以通过编译, 但是运行时会得到 java.lang.ClassCastException 异常, 如果使用泛型的话,

        List<Integer> list = new ArrayList<>();
        list.add(55);
        list.add("dd"); // 编译错误
        System.out.println(((Integer) list.get(1)) - 5);

到这里我们明白了:

 java 之所以引入泛型是为了增强程序的安全性和正确性, 以便在编译期就能检查出类型相关的错误.

那么既然这样, 为什么不能使用泛型数组呢?  首先假设如果可以使用泛型数组, 我们看下面一段代码:

        List<Integer>[] list = new ArrayList<Integer>[10]; // 泛型数组
        Object[] objects = list;

        List<String> stringList = new ArrayList<>();
        stringList.add("dd");

        objects[0] = stringList;

        Integer s = ((List<Integer>) objects[0]).get(0);
        System.out.println(s);

如果可以使用泛型数组, 这段代码在编译期间没有任何问题, 但是在运行期又会出现烦人的 java.lang.ClassCastException , 我们来分析下为什么:

  1. 首先我们知道, java中的数组是可以向上转型成基类的数组的, 这个不用多说, java中的引用多态的机制.
  2. 然后我们知道 java 中的泛型实现的原理是类型擦除, 因此我们上面定义的 list<Integer> 和 list<String> 都会被擦除成 list<Object>, 所以我们可以在 objects 中加入 list<string> 这种类型的引用.
  3. 当我们加入 list<string> 这种类型的引用后, 如果我们按照原来定义泛型数组时使用的 list<integet> 类型来访问数组中的元素的话固然又会引入 java.lang.ClassCastException.

综上所述, 可以用一句话来描述 java 为什么不能创建泛型数组:

使用泛型的作用是使得程序在编译期可以检查出与类型相关的错误,但是如果使用了泛型数组,这种能力就会受到破坏.


参考博文:

https://blog.csdn.net/x_iya/article/details/79550667

http://www.blogjava.net/sean/archive/2005/08/09/9630.html

http://www.blogjava.net/deepnighttwo/articles/298426.html

猜你喜欢

转载自blog.csdn.net/DJH2717/article/details/82824635