Java 2d int数组是否通用?为什么?

时间:2018-04-06 02:52:24

标签: java arrays generics types

我知道原始整数(int[] arr = new int[5])的Java数组不被视为通用对象,因此它不能作为Arrays.sort(T[] a, Comparator<? super T> c)ArrayList.toArray(T[] a)的参数提供。

但是我刚发现2d数组的原始整数可以作为上述方法的参数!代码如下。

int[][] points = new int[3][3];
Arrays.sort(points, (a, b) -> a[1] - b[1]);

List<int[]> list2 = new ArrayList<>();
list2.add(new int[]{1,3,5});
list2.add(new int[]{2});
int[][] array2 = list2.toArray(new int[5][5]);
for(int[] i : array2)
  System.out.println(Arrays.toString(i));

怎么可能?是因为2d int数组被视为原始int数组的数组,其中内部数组本身不是原始数组?这种行为背后的设计是什么?

2 个答案:

答案 0 :(得分:5)

与许多其他接受泛型类型的方法一样,

Arrays::sort被重载以支持基本类型,请参阅the JavaDocs。事实上,Arrays::sort有18种变体:

static void sort(byte[] a)
static void sort(byte[] a, int fromIndex, int toIndex)
static void sort(char[] a)
static void sort(char[] a, int fromIndex, int toIndex)
static void sort(double[] a)
static void sort(double[] a, int fromIndex, int toIndex)
static void sort(float[] a)
static void sort(float[] a, int fromIndex, int toIndex)
static void sort(int[] a)
static void sort(int[] a, int fromIndex, int toIndex)
static void sort(long[] a)
static void sort(long[] a, int fromIndex, int toIndex)
static void sort(Object[] a)
static void sort(Object[] a, int fromIndex, int toIndex)
static void sort(short[] a)
static void sort(short[] a, int fromIndex, int toIndex)
static <T> void sort(T[] a, Comparator<? super T> c)
static <T> void sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c)

正如您所看到的,除了采用Comparator的所有内容都被重载以接受所有基元以及通用数组类型。

至于为什么static <T> void sort(T[] a, Comparator<? super T> c)接受类型为int[][]的对象,但的对象为int[]类型的对象:int[][]是一个数组int[]的{​​{1}},与Object不同,是一种扩展int的类型。 int[][]是一个对象数组,而不是一个基元数组。

答案 1 :(得分:1)

这怎么可能?

这是可能的,因为调用的重载方法是:static <T> void sort(T[] a, Comparator<? super T> c)。在此调用中,T将等同于[I

是因为2d int数组被视为原始int数组的数组,其中内部数组本身不是原始数据?

你注意到内部数组不是原始数据是正确的。内部数组实际上是一个类:[I。事实上,如果你运行以下代码,你肯定会证明它确实是一个类。

public static void main(String[] args){
    int[] i = new int[]{1,2};
    System.out.println(i.getClass());

    int[][] i2d = new int[][]{{1},{2},{3}};
    System.out.println( i2d.getClass() );
    System.out.println( i2d[0].getClass() );
}

实际上,i2d[0]代表i代表的同一个类。

此行为背后的设计是什么?

设计是一个数组必须是一个对象。数组将在堆上初始化,因此我们需要一个指向它的指针。