【发布时间】:2021-12-01 11:37:01
【问题描述】:
我刚刚开始学习 Java 中的泛型。我需要一些帮助来了解如何将数组转换为泛型类型。
以下代码来自 Y. Daniel Liang 的《Java 编程简介》第 19 章。代码被缩短以显示我缺少理解的地方。
GenericMatrix.java:
public abstract class GenericMatrix<E extends Number> {
protected abstract E add(E o1, E o2);
public E[][] addMatrix(E[][] matrix1, E[][] matrix2) {
// Check bounds of the two matrices
if ((matrix1.length != matrix2.length) ||
(matrix1[0].length != matrix2[0].length)) {
throw new RuntimeException(
"The matrices do not have the same size");
}
E[][] result = (E[][])new Number[matrix1.length][matrix1[0].length];
for (int i = 0; i < result.length; i++)
for (int j = 0; j < result[i].length; j++) {
result[i][j] = add(matrix1[i][j], matrix2[i][j]);
}
return result;
}
IntegerMatrix.java:
public class IntegerMatrix extends GenericMatrix<Integer> {
@Override /** Add two integers */
protected Integer add(Integer o1, Integer o2) {
return o1 + o2;
}
}
TestIntegerMatrix.java:
public class TestIntegerMatrix {
public static void main(String[] args) {
Integer[][] m1 = new Integer[][]{{1, 2, 3}, {4, 5, 6}, {1, 1, 1}};
Integer[][] m2 = new Integer[][]{{1, 1, 1}, {2, 2, 2}, {0, 0, 0}};
IntegerMatrix integerMatrix = new IntegerMatrix();
Integer[][] m3 = (Integer[][])integerMatrix.addMatrix(m1, m2);
}
}
我的理解是,由于我将我的 GenericMatrix 实例声明为 Integer,那么 addMatrix 方法应该返回一个 Integer[][](整数类型的二维数组)。这就是我这样声明 m3 变量的原因。当我编译这段代码时,它编译没有任何错误。但是当我运行它时,我得到了 Number 无法与 Integer 协调的错误。如果我将 m3 更改为 Number[][] 一切正常。
据我了解,泛型的主要好处是避免了这个问题。编译器会捕捉到这一点。但我更想知道的是为什么它不返回一个 Integer[][]。
根据本书,您不能创建泛型类型的数组。为了规避这个问题,你将它转换为泛型类型。但是我在这里看到演员表不起作用
书上的练习:
“限制 2: 不能使用 new E[] 不能使用 泛型类型参数。例如,下面的语句是 错误:E[] 元素 = 新 E[容量];你可以绕过这个 通过创建一个 Object 类型的数组然后将其转换为 E[],如下:E[] elements = (E[])new Object[capacity];"
既然 E 被实例化为整数,为什么我的代码不将返回的结果数组实例化为整数?
请帮助我理解这一点。任何有关阅读材料的建议将不胜感激。
谢谢你, 伊斯尔
【问题讨论】:
-
您正在寻找的概念是类型擦除。
-
Java 数组协方差is a lie。不要向下转换数组;它只会导致悲伤。
-
@SilvioMayolo 我已经看到了你在这里展示的内容。但是我没有得到的是,因为我使用的是泛型,而我的 IntegerMatrix 类正在实例化 GenericMatrix 广告,所以 Integer 不应该意味着这个实例都应该是一个 Integer 吗?
-
@chrylis-cautiouslyoptimistic- 擦除后数组不应该是整数数组(更准确地说是整数数组的数组)
-
不,删除后编译器能做的最好的事情是
Number[]。这就是 C++ 模板和 Java 泛型的区别。