У меня есть клиентский класс, который я не могу изменить.
List<Integer> list1= Arrays.asList(1,2,3);
System.out.println("Total sum is:"+sum(list1));
printlist(list1);
List<Double> list2=Arrays.asList(1.0,2.0,3.0);
System.out.println("Total sum is:"+sum(list2));
printlist(list2);
У меня здесь есть бизнес-логика
private static Object sum(List<? extends Number> list) {
double sum = 0;
for (Number i: list) {
sum+=i.doubleValue();
}
return sum;
}
Поэтому я хочу вернуть 6 для целого числа и 6.0 для двойного. Как я могу это сделать? Я думаю о приведении суммы как int или double в зависимости от типа, но из-за стирания типа вся информация теряется. Кто-нибудь может мне помочь?
Сейчас я не проверяю это условие. Я просто пытаюсь понять дженерики. Я новичок в дженериках
Нет другого способа узнать, что это за список, кроме как проверить его содержимое.
Так вы можете изменить метод «бизнес-логики»?
вы можете использовать переопределение, даже java делает это
или посмотрите следующее: stackoverflow.com/questions/1759549/…




Используйте instanceof
if ( i instanceof Double) {
System.out.println("param is a Double");
}
else if ( i instanceof Integer) {
System.out.println("param is an Integer");
}
Объекты в списке все еще имеют информацию о типе, связанную с ними во время выполнения. Единственные стертые типы - это типы дженериков (например, List в вашем примере). Дженерики проверяются во время компиляции, но не поддерживаются в сгенерированном байт-коде. Это означает, что вы можете использовать instanceof для проверки содержание коллекции:
private static Object sum(List<? extends Number> list) {
Integer integerSum = 0;
Double doubleSum = 0.0;
boolean hasDouble = false;
for (Number i: list) {
if (i instanceof Integer) {
integerSum += i.intValue();
} else {
doubleSum += i.doubleValue();
hasDouble = true;
}
}
if (hasDouble)
return doubleSum + integerSum;
return integerSum;
}
Код имеет некоторые особенности для обработки смешанных списков и некорректно обрабатывает Long, Short, Byte и т. д.
Конструктор Double вызывать не нужно. Просто верните doubleSum + integerSum.
Вы можете использовать double, чтобы суммировать все значения и привести его в конце.
Опасно предполагать, что экземпляр подкласса Number может быть представлен с помощью double. Чтобы сделать это безопасно, вам нужно проверить все возможные типы.
@SuppressWarnings("unchecked")
private static <T extends Number> T sum(List<T> list) {
Objects.requireNonNull(list);
if (list.isEmpty() || list.contains(null))
throw new IllegalArgumentException();
Class<T> clazz = (Class<T>) list.get(0).getClass();
if (clazz == Integer.class) {
return (T) (Integer) list.stream().mapToInt(i -> (Integer) i).sum();
}
else if (clazz == Double.class) {
return (T) (Double) list.stream().mapToDouble(i -> (Double) i).sum();
}
/* And other Number subclass types */
// Not possible if all types covered
throw new IllegalStateException();
}
Здесь - это вопрос / ответ, связанный с этим.
Что, если это смесь
IntegerиDouble?