Подтвердить что ты не робот

Java Generics WildCard: <? extends Number> vs <T extends Number>

В чем разница между этими двумя функциями?

static void gPrint(List<? extends Number> l) {
    for (Number n : l) {
        System.out.println(n);
    }
}

static <T extends Number> void gPrintA(List<T> l) {
    for (Number n : l) {
        System.out.println(n);
    }
}

Я вижу тот же результат.

4b9b3361

Ответ 1

В этом случае нет разницы, потому что T больше никогда не используется.

Причина объявления T заключается в том, что вы можете ссылаться на него снова, таким образом связывая два типа параметров или тип возврата вместе.

Ответ 2

Разница в том, что вы не можете ссылаться на T при использовании подстановочного знака.

Вы не сейчас, так что "нет разницы", но вот как вы могли бы использовать T, чтобы иметь значение:

static <T extends Number> T getElement(List<T> l) {
    for (T t : l) {
        if (some condition)
            return t;
    }
    return null;
}

Это вернет тот же тип, что и все, что передается. Например, они будут скомпилированы:

Integer x = getElement(integerList);
Float y = getElement(floatList);

Ответ 3

T - это ограниченный тип, т.е. какой бы тип вы ни использовали, вы должны придерживаться этого конкретного типа, который расширяет Number, например. если вы передадите тип Double в список, вы не можете передать ему тип Short, поскольку T имеет тип Double, и список уже ограничен этим типом. В отличие от этого, если вы используете ? (wildcard), вы можете использовать "любой" тип, который расширяет Number (добавьте в этот список как Short, так и Double).

Ответ 4

Когда вы используете T, вы можете выполнять все действия в списке. Но когда вы используете, вы не можете выполнить добавление.

T - так же, как ссылка на объект с полным доступом
? - предоставить частичный доступ

static void gPrint(List<? extends Number> l) {
 l.add(1); //Will give error
for (Number n : l) {
    System.out.println(n);
}

static <T extends Number> void gPrintA(List<T> l) {
l.add((T)1); //We can add
for (Number n : l) {
    System.out.println(n);
}