Я только начал изучать дженерики с Java, поэтому я создал небольшой проект для себя. Я хотел создать Вектор / Точку, где вы могли бы указать Number
(например, Double
, Integer
, Long
и т. Д.).
В итоге я получил достойный объект класса, но заметил некоторые проблемы, связанные с методами.
import java.math.BigDecimal;
@SuppressWarnings("WeakerAccess") // Suppresses weaker access warnings
public class Vector<T extends Number> {
private T x;
private T y;
public Vector() {}
public Vector(T x, T y) {
this.x = x;
this.y = y;
}
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
public void dislocate(T offsetX, T offsetY) {
this.setX(addNumbers(getX(), offsetX));
this.setY(addNumbers(getY(), offsetY));
}
public void dislocate(Vector vector) {
this.setX(addNumbers(getX(), vector.getX()));
this.setY(addNumbers(getY(), vector.getY()));
}
@SuppressWarnings("unchecked") // Suppresses cast unchecked warnings
private T addNumbers(Number... numbers) {
BigDecimal bd = new BigDecimal(0);
for(Number number : numbers) {
bd = bd.add(new BigDecimal(number.toString()));
}
return (T) bd;
}
}
Последний метод, который является методом добавления чисел, выдает предупреждение о неконтролируемом приведении. После того, как я провел некоторое исследование, я обнаружил, что он ведет себя странно из-за генериков, в которых я относительно новичок и не могу должным образом устранить неполадки.
А как же return (T) bd;
создает предупреждение? T
должен быть экземпляром Number
, поэтому его можно преобразовать в BigDecimal
, верно?
Итак, я создал свой маленький метод тестирования,
Vector<Double> vec = new Vector<>(1.0, 3.0);
Vector<Double> vec2 = new Vector<>(2.2, 3.9);
vec.dislocate(1.0, 2.7);
System.out.println(vec.getX() + " " + vec.getY());
vec.dislocate(vec2);
System.out.println(vec.getX() + " " + vec.getY());
Отлично работает, распечатывает 2.0 5.7
и 4.2 9.6
.
Тогда возникает проблема, когда я использую метод из Double
, например Double#isNaN()
. Затем он выбрасывает ClassCastException, Exception in thread "main" java.lang.ClassCastException: java.base/java.math.BigDecimal cannot be cast to java.base/java.lang.Double
.
Это казалось довольно распространенным явлением с другими проблемами, с которыми люди сталкивались с этим, однако, несмотря на перебор ресурсов, я не понимаю , почему ошибка генерируется с помощью методов Double
. Объект должен быть Double
после приведения, верно?