使用 Comparable 转换 Object 的实例

Cast instance of Object with Comparable

我在看一个 mergeSort 方法,我有一些问题。 有一个Object转换成Comparable,就是一个接口。

((Comparable)dest[j-1]).compareTo((Comparable)dest[j])

当有cast接口时,编译器到底做了什么? .compareTo 方法未在 Object class 中定义。 接口只有抽象方法。如何在 Object 中使用?

private static void mergeSort(Object src[], Object dest[], int low, int high) {
    int length = high - low;

    // Insertion sort on smallest arrays
    if (length < 7) {
        for (int i=low; i<high; i++)
          for (int j=i; j>low && ((Comparable)dest[j-1]).compareTo((Comparable)dest[j]) >0; j--)
              swap(dest, j, j-1);
        return;
    }
    // Recursively sort halves of dest into src
    int mid = (low + high)/2;
    mergeSort(dest, src, low, mid);
    mergeSort(dest, src, mid, high);

    // If list is already sorted, just copy from src to dest.  This is an
    // optimization that results in faster sorts for nearly ordered lists.
    if (((Comparable)src[mid-1]).compareTo((Comparable)src[mid]) <= 0) {
        System.arraycopy(src, low, dest, low, length);
        return;
    }
    // Merge sorted halves (now in src) into dest
    for(int i = low, p = low, q = mid; i < high; i++){
        if (q>=high || p<mid && ((Comparable)src[p]).compareTo(src[q])<=0)
            dest[i] = src[p++];
        else
            dest[i] = src[q++];
    }
}

dest[j-1]是一个引用,它引用了一个Object,这个Object可能实现了Comparable.

使用 (Comparable)dest[j-1],你是在告诉编译器 相信我,我是可比的

在运行时,如果这个对象是可比较的,那很好。不行,ClassCastException会被抛出

Object o = 1; // Integer is Comparable
System.out.println(((Comparable)(o)).compareTo(0)); // 1

Object o = new ArrayList<Integer>(); // ArrayList is not Comparable
System.out.println(((Comparable)(o)).compareTo(0)); // ClassCastException

这部分是由于泛型出现之前的遗留问题,当时许多核心 Java 函数都采用 Object 作为参数,你不得不到处投射东西。

此外,Arrays class 也可以对 int 等内在事物进行排序

这里发生的事情是 mergeSort 假设对象实现了 Comparable and calls it's compareTo method. This assumption will cause a fail fast ClassCastException,所以这不是一个坏假设。

TLDR:在大多数情况下,对象 实现 Comparable 因此它是安全的。