Я изучаю дженерики Java, и я задаю себе этот вопрос.
В чем разница между этими двумя объявлениями методов?
public static void someMethod(List<? extends Number> numberList);
и
public static <E extends Number> void someMethod(List<E> numberList);
Я изучаю дженерики Java, и я задаю себе этот вопрос.
В чем разница между этими двумя объявлениями методов?
public static void someMethod(List<? extends Number> numberList);
и
public static <E extends Number> void someMethod(List<E> numberList);
В последнем вы ссылаетесь на тип в пределах someMethod, а именно E. В первом вы этого не делаете.
Основное отличие состоит в том, что последний является общим методом, который не является первым.
Итак, например, в последнем методе вы можете сделать что-то вроде этого:
public static <E extends MyObject> void someMethod(List<E> someList) {
E myObject = someList.iterator().next(); // this can actually lead to errors
myObject.doSomething(); // so treat it as an example
}
Это означает, что вы можете заменить произвольный тип E, который соответствует правилу в объявлении универсального метода и сможет использовать этот тип в вашем методе.
Следует помнить, что вы должны вызвать общий метод с аргументами типа следующим образом:
someClass.<MyArbitraryType>someMethod(someList);
Вы можете найти общий обзор общих методов здесь.
Во второй версии вы можете сделать что-то вроде:
public static <E extends Number> void someMethod(List<E> numberList) {
E number = numberList.get(0);
numberList.add(number);
}
Это невозможно в первой версии.
Использование первого объявления метода не позволит вам добавить что-то новое в список. Например, это не скомпилируется.
public static void someMethod(List<? extends Number> numberList, Number number) {
numberList.add(number);
}
в то время как второй позволяет вам сделать это:
public static <T extends Number> void someMethod(List<T> numberList, T number) {
numberList.add(number);
}