Arrays类中的sort方法为什么不定义为接收一个Comparable[]数组

Arrays类中的sort方法为什么不定义为接收一个Comparable[]数组

有人认为,将Arrays类中的sort方法定义为接受一个Comparable[]数组就可以在使用元素类型没有实现Comarable接口的数组作为参数调用sort方法时,由编译器给出错误报告,但事实并非如此,为什么呢?

参考:https://www.zhihu.com/question/67693996/answer/255459062
http://www.imooc.com/wenda/detail/551503

1、数组是协变的

数组是协变的,即如果Sub为Super的子类型,那么数组类型Sub[]就是Super[]的子类型。可以将一个Comparable[]数组转换为Object[],反之则不行。如果Arrays.sort()方法声明为接收Comparable[]数组,那么在一开始调用的时候就要实例化一个Comparable[]数组或者兼容数组,这就会引起一种不便:即Java的部分API拿到就是Object[](比如Collection的toArray()方法),而即使你的Object[]内部对象的实际类型全部是Comparable兼容的,也不能把Object[]类型转换成Comparable[],因为Java认为它们类型不同,如果你调用某个API意外地得到了Object[]类型而又需要排序的话,你就得不得不复制一个新的Comparable[]数组出来排序,而这个是没有任何必要的,所以Java就这样设计API了。

2、泛型数组是非法的

Comparable<T>[] 泛型数组是非法的,而使用原生态类型是不安全的,应该尽量避免。

首先:创建泛型、参数化类型或者类型参数的数组是非法的,以下创建数组表达式没有一个是合法的:

new List<E>[], new List<String>[], new E[]

下文引用Effective Java的内容解释一下为什么泛型数组是非法的.

List<String>[] StringLists = new List<String>[1];           // (1)
List<Integer> intList = List.of(42);                        // (2)
Object[] objects = StringLists;                             // (3)
objects[0] = intList;                                       // (4)
String s = stringLists[0].get(0);                           // (5)

假设第一行是合法的,它创建了一个泛型数组。第二行创建并初始化了一个包含单个元素的List<Integer>.第三行将List<String>数组保存到一个Object数组变量中,这是合法的,因为数组是协变的。第四行将List<Integer>保存到Object数组里面唯一的元素中,这是可以的,因为泛型是通过擦除实现的:List<Integer>实例运行时类型只是List,List<String>[]实例的运行时类型则是List[],第五行中我们从这个数组里唯一的列表中获取了唯一的元素。编译器自动地将获取到的元素转换成String,但它是一个Integer,因此,我们在运行时得到了一个ClassCastEcxeption异常。为了防止出现这种情况,(创建泛型数组的)第一行必须产生一条变异时的错误。

3、Collections.sort()方法

Collections.sort()方法:此方法对参数做了限制,<T extends Comparable<? super T>>
其内部实现也是调用了Arrays.sort()方法。

  public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }
default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

在这里插入图片描述
ps:第一篇技术博客,也是临时起意,想记录一下,大部分都是抄的,就当是平常的做了个笔记,自己巩固一遍,也方便日后复习。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值