I am creating a Matrix class (just for experiment) with generic type
import java.lang.reflect.Array;
import java.util.Arrays;
@SuppressWarnings("unused")
public class Matrix<T extends Number> {
private int nRow;
private int nCol;
private T[] elements;
private T[][] elementsGrid;
public Matrix(int nRow, T[] elements) {
this(nRow, nRow, elements);
}
public Matrix(int nRow, int nCol, T[] elements) {
if (elements.length != nRow * nCol) {
throw new IllegalArgumentException(
"Incorrect size: Expected(" nRow * nCol "), but provided(" elements.length ")");
}
this.nRow = nRow;
this.nCol = nCol;
this.elements = elements;
@SuppressWarnings("unchecked")
T[][] t = (T[][]) Array.newInstance(elements.getClass().getComponentType(), new int[] { nRow, nCol });
elementsGrid = t;
for (int i = 0; i < nRow; i ) {
for (int j = 0; j < nCol; j ) {
elementsGrid[i][j] = elements[i * nCol j];
}
}
System.out.println(Arrays.deepToString(elementsGrid));
}
Basically i am just taking a single dim array and copying it to double dim array. The code works fine, but I had to struggle a lot with this, and I am not sure if this is indeed the correct way to handle this. For e.g. if I remove the @SuppressWarnings("unchecked"), it gives me the warning, of unchecked cast. Is it fine to ignore this warning, since I have already declared my generic to only allow subclasses of Number
.
CodePudding user response:
Both Class.getComponentType
and Array.newInstance
are a bit primitive. You can merely do:
Object[][] t = (Object[][]) Array.newInstance(elements.getClass().getComponentType(),
nRow, nCol); // Object is actually type T.
But that actually is even formally wrong. It should be T. So your version is not worse.
Look at this:
int[][] t = (int[][]) Array.newInstance(int.class, nRow, nCol);
Not feasible with generics.
For a run-time cast:
Class<?> ctype = elements.getClass().getComponentType();
ctype.cast(object);
An improvement would seem:
// Array:
static <C> C[] newInstance(Class<C> componentType, int length);
Unfortunately you also can have int.class
besides Integer.class
for int[].class
and Integer.class
.
The language means of the typing system in java do not form a complete "algebra" with which to describe all this.
However in a couple of year we will see List<int>
.
Meanwhile either look for a more complete language or try ArrayList<T>
instead of T[]
with an explicit Class<T> componentType
to represent the missing getComponentType().