Использование подтипа в качестве параметра типа в классе

Рассмотрим следующие фрагменты кода

    public static <T> String typeName1(Class<T extends Object> c) {
        return c.getSimpleName();
    }
    public static  String typeName2(Class<? extends Object> c) {
        return c.getSimpleName();
    }

Первый показывает ошибку времени компиляции, а второй успешно компилируется. Почему это так?


person Hariharan    schedule 18.03.2015    source источник


Ответы (1)


Измените первый на это:

public static <T extends Object> String typeName(Class<T> c) {
    return c.getSimpleName();
}

и это будет работать. Это разница в том, где вы ставите границы. Для параметра типа вы объявляете границы там, где вы объявляете параметр типа, а не там, где вы его используете. В то время как для подстановочных знаков, поскольку такого объявления нет, вы указываете границы, как и где вы его используете. Кстати, <T extends Object> может быть просто <T>.

public static <T> String typeName(Class<T> c) {
    return c.getSimpleName();
}
person Rohit Jain    schedule 18.03.2015
comment
Но если мы используем уровень параметров, аргументы, передаваемые методу, будут ограничены, будет ли вышеописанный делать то же самое? - person Hariharan; 18.03.2015
comment
@harinewton Вышеуказанные методы могут принимать все те аргументы, которые можно передать методу typeName2() с имеющимся у вас подстановочным знаком. - person Rohit Jain; 18.03.2015
comment
Здесь я использую Object только для понимания - person Hariharan; 18.03.2015
comment
Например, предположим, что мне нужно взять классы, которые являются подклассами CharSequence, можно ли выполнить эту проверку, если мы просто возьмем класс с параметром типа T? - person Hariharan; 18.03.2015
comment
@harinewton Нет. Для этого вы должны дать оценку - <T extends CharSequence>. - person Rohit Jain; 18.03.2015
comment
Это мой вопрос, почему это не разрешено. Есть ли причина? - person Hariharan; 18.03.2015
comment
@harinewton Если вы просто используете <T>, это означает, что он может принимать любой тип. Если вы хотите ограничить тип подтипом CharSequence, вы должны указать границы - <T extends CharSequence> означает, что T может быть чем-то, что расширяет CharSequence, поэтому вы не сможете передать Object.class, где метод принимает Class<T> в качестве параметра. - person Rohit Jain; 18.03.2015