При подготовке к экзамену SCJP-6 I сталкивающийся со сложным вопросом. Я не могу найти ответ один. Ответ для вопроса и дает короткие комментарии:
abstract class A<K extends Number> {
// insert code here
}
public abstract <K> A<? extends Number> useMe(A<? super K> k);
public abstract <K> A<? super Number> useMe(A<? extends K> k);
public abstract <K> A<K> useMe(A<K> k);
public abstract <V extends K> A<V> useMe(A<V> k);
public abstract <V super K> A<V> useMe(A<V> k);
public abstract <V extends Character> A<? super V> useMe(A<K> k);
public abstract <V super Character> A<? super V> useMe(A<K> k);
Какой метод может быть вставлен в заполнителя выше?
P.S. Я пытался считать спецификацию. Они каждый не был полезен для меня.
Только второй ( общедоступный аннотация A useMe (A k);
), похоже, работает, просто подключив его к IDE.
Лучший способ сделать это - попробовать каждый из них и посмотреть, что вам сообщает компилятор. Я получаю следующие результаты для каждого из них (с использованием NetBeans, поэтому ваши результаты могут незначительно отличаться):
public abstract <K> A<? extends Number> useMe(A<? super K> k);
// seems to work
public abstract <K> A<? super Number> useMe(A<? extends K> k);
// type parameter ? extends K is not within its bound
public abstract <K> A<K> useMe(A<K> k);
// type parameter K is not within its bound
public abstract <V extends K> A<V> useMe(A<V> k);
// seems to work
public abstract <V super K> A<V> useMe(A<V> k);
// > expected
// illegal start of type
// <identifier> expected
// missing method body, or declare abstract
// cannot find symbol
// symbol: class V
// location: class A<K>
public abstract <V extends Character> A<? super V> useMe(A<K> k);
// type parameter ? super V is not within its bound
public abstract <V super Character> A<? super V> useMe(A<K> k);
// > expected
// illegal start of type
// <identifier> expected
// missing method body, or declare abstract
Попробую объяснить немного подробнее ...
1 не работает, потому что вы не можете заменить A super K>
для A
... нет гарантии, что суперкласс расширяет тот же класс, что и подкласс.
1, 2 и 3 не работают, потому что параметр начального типа скрывает исходный K, используемый в объявлении класса.
5 не работает, потому что
не может заменить
... нет гарантии, что суперкласс расширяет тот же класс, что и подкласс.
6 и 7 должны быть очевидны.
4 работает, потому что если мы знаем, что V расширяет K, то мы знаем, что V расширяет Number (поскольку все классы, которые K расширяет V, расширяются). Поэтому мы можем заменить A
на
.
Надеюсь, это имеет смысл ... кто-то может прийти и объяснить лучше.