Ошибка Cannot infer type arguments for Array<> как можно исправить?
Ошибка в строке:
Array<T> result = new Array<>(arr.getClass().getComponentType(), size);
Вот часть кода:
class Array<T> {
T[] arr;
private int size;
public Array(Class<T> c, int size) {
arr = (T[]) java.lang.reflect.Array.newInstance(c, size);
this.size = size;
}
public T get(int index) {
return arr[index];
}
public void set(int index, T value) {
arr[index] = value;
}
public int length() {
return size;
}
public Array<T> add(Array<T> other) {
Array<T> result = new Array<>(arr.getClass().getComponentType(), size);
for (int i = 0; i < size; i++) {
T element1 = arr[i];
T element2 = other.get(i);
if (element1 instanceof Number && element2 instanceof Number) {
Number sum = ((Number) element1).doubleValue() + ((Number) element2).doubleValue();
result.set(i, (T) sum);
} else if (element1 instanceof String && element2 instanceof String) {
String concat = (String) element1 + element2;
result.set(i, (T) concat);
} else {
throw new RuntimeException("Unsupported Type");
}
}
return result;
}
Ответы (1 шт):
Кроме проблемы с преобразованием типа, которую можно решить при помощи кастинга согласно комментария от @Byb:
Array<T> result = new Array<>((Class<T>) arr.getClass().getComponentType(), size);
в методе add есть и другие проблемы, связанные с типом результата сложения отдельных элементов.
Данный код отработает только если создан массив чисел с двойной точностью Array<Double>
if (element1 instanceof Number && element2 instanceof Number) {
Number sum = ((Number) element1).doubleValue() + ((Number) element2).doubleValue();
result.set(i, (T) sum);
}
Для любого другого численного типа будет выброшено исключение:
Exception in thread "main" java.lang.ArrayStoreException: java.lang.Double
в строке метода set:
arr[index] = value;
так как результат sum получит тип Double после боксинга результата (Number::doubleValue возвращает примитив double!), а у массива будет к примеру тип Integer[] arr.
Поэтому следует принудительно использовать методы valueOf классов-обёрток и затем ещё приведение к типу T (плюс ещё кастинг к "коротким" целочисленным типам, так как оператор + автоматически расширяет до int):
public Array<T> add(Array<T> other) {
Array<T> result = new Array<>((Class<T>)arr.getClass().getComponentType(), size);
for (int i = 0; i < size; i++) {
T element1 = arr[i];
T element2 = other.get(i);
if (element1 instanceof Number && element2 instanceof Number) {
Number n1 = (Number) element1;
Number n2 = (Number) element2;
Number sum;
if (n1 instanceof Double) {
sum = Double.valueOf(n1.doubleValue() + n2.doubleValue());
} else if (n1 instanceof Byte) {
sum = Byte.valueOf((byte)(n1.byteValue() + n2.byteValue()));
} else if (n1 instanceof Float) {
sum = Float.valueOf(n1.floatValue() + n2.floatValue());
} else if (n1 instanceof Short) {
sum = Short.valueOf((short)(n1.shortValue() + n2.shortValue()));
} else {
sum = Integer.valueOf(n1.intValue() + n2.intValue());
}
result.set(i, (T) sum);
} else if (element1 instanceof String && element2 instanceof String) {
String concat = (String) element1 + element2;
result.set(i, (T) concat);
} else {
throw new RuntimeException("Unsupported Type");
}
}
return result;
}