为什么我不能在 Java 中创建通用数组?

Why can't I create generic array in Java?

我在创建一些数组时遇到了问题。

这是代码

Predicate<Integer[]>[] endOfLine = {
    curPoint -> curPoint[0]==r2,
    curPoint -> curPoint[0]==c2,
    curPoint -> curPoint[0]==r1,
    curPoint -> curPoint[0]==c1
};
Consumer<Integer[]>[] move = {
    curPoint -> { curPoint[0]++; },
    curPoint -> { curPoint[1]++; },
    curPoint -> { curPoint[0]--; },
    curPoint -> { curPoint[1]--; }            
};

和 eclipse(也许是编译器?)说:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    Cannot create a generic array of Predicate<Integer[]>

Google了一下,发现Java中不能做泛型参数数组。

我看了编译时间和运行时间,我想这可能不是我的问题。

我看到一些编译编译的代码:

List<Integer>[] arrayOfLists = new ArrayList[2];
ArrayList<Integer[]> lists =new ArrayList<>();
ArrayList<Consumer []> [] lists = new ArrayList[5];
        
Predicate<Integer[]>[] p = new Predicate[5];
p[0] = a -> a[0] == 0;

Predicate<Integer[]>[] pp = { a -> a[0] == 0 }; //cant be compile

并且我阅读了 oracle 文档并发现了这个:

"Cannot Create Arrays of Parameterized Types"

我总结了我的快捷语法,{} 是问题所在。快捷语法创建具有参数化类型的代码。这是正确的吗?

您无法在 Java 中创建通用数组。数组是可具体化的类型,在运行时携带它们的类型信息,而泛型是不可具体化的,它们的类型信息在编译时由于擦除而被擦除。这是由于 java 中类型系统的实现,尽管这会导致一些粗糙的边缘和角落情况,但它简化了代码向泛型的演变。由于泛型类型信息被删除,您在运行时没有它们,这就是为什么您不能在 java.

中创建泛型数组的原因

有两种解决方案可以解决您面临的问题。您可以创建一个对象数组并将其转换为您需要的通用类型。

final T[] arr = (T[]) new Object[n]

否则

final Object[] arr = new Object[]

当你从这个数组中获取项目时,你可以像这样进行转换

T itm = (T) arr[1];

如果您不return这个内部数组,上述两种方法都有效。

但是,如果您正在 return 内部数组,则需要以反射方式创建它,因为您需要维护正确的具体化类型。

static <T> T[] createArr(Class<T> clz) {
    return (T[]) Array.newInstance(clz, 5);
}