I've just started learning about generics in Java. I need some help in understanding about casting an array to the generic type.
The following code is from the book Introduction to Java Programming by Y. Daniel Liang Chapter 19. The code is shortened to show where I'm missing understanding.
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);
}
}
My understanding is that since I'm declaring my instance of GenericMatrix as an Integer, then the addMatrix method should return an Integer[][] (2 dimensional array of type Integer). This is why I declared m3 variable as such. When I compile this code it compiles without any error. But when I run it I get the error that Number can't ve concerted to Integer. if I change m3 to Number[][] everything works.
From what I understood the main gain of generics is to avoid this issue. That the compiler would catch this. But what I wonder even more is why wouldn't it return an an Integer[][].
As per the book you can't create an array of a generic type. to circumvent this problem you cast it to the generic type. But fron I'm seeing here the cast doesn't work
Exert from book:
"Restriction 2: Cannot Use new E[] You cannot create an array using a generic type parameter. For example, the following statement is wrong: E[] elements = new E[capacity]; You can circumvent this limitation by creating an array of the Object type then casting it to E[], as follows: E[] elements = (E[])new Object[capacity];"
Why wouldn't my code instantiate the returned result array as an Integer since E is instantiated as an Integer?
Please help me understand this. Any suggestions on reading material would be greatly appreciated.
Thank You, Isr