Вопрос по экзамену SCJP-6 - PullRequest
6 голосов
/ 26 мая 2010

При подготовке к экзамену SCJP-6 я столкнулся с трудной проблемой. Я не могу найти ответ сам. Пожалуйста, ответьте на вопрос и дайте короткие комментарии:

abstract class A<K extends Number> {
   // insert code here
}    
  1. public abstract <K> A<? extends Number> useMe(A<? super K> k);

  2. public abstract <K> A<? super Number> useMe(A<? extends K> k);

  3. public abstract <K> A<K> useMe(A<K> k);

  4. public abstract <V extends K> A<V> useMe(A<V> k);

  5. public abstract <V super K> A<V> useMe(A<V> k);

  6. public abstract <V extends Character> A<? super V> useMe(A<K> k);

  7. public abstract <V super Character> A<? super V> useMe(A<K> k);

Какой метод можно вставить в заполнитель выше?

P.S. Я пытался посмотреть на спецификации. Эти мне не помогли.

Ответы [ 4 ]

3 голосов
/ 28 июля 2010

Ответ 1,2,3: универсальный тип K тип затененного класса K. В этих методах K это просто новый универсальный тип. Компилятор пытается пройти условную оценку <K extends Number>. Метод 1,2 проходит, а 3 - не проходит.

Ответ 4 полностью правильный.

Ответ 5,7 имеет синтаксическую ошибку.

Ответ 6 неправильный, потому что тест <V extends Number> не пройден.

3 голосов
/ 26 мая 2010

Лучший способ сделать это - попробовать каждый и посмотреть, что говорит вам компилятор. Я получаю следующие результаты для каждого из них (используя 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 голос
/ 26 мая 2010

Я постараюсь объяснить немного больше ...

1 не работает, потому что вы не можете заменить A<? super K> на A<K extends Number> ... нет гарантии, что суперкласс расширяет тот же класс, что и подкласс.

1, 2 и 3 не работают, поскольку исходный параметр типа скрывает исходный K, используемый в объявлении класса.

5 не работает, потому что <V super K> не может заменить <K extends Number> ... нет гарантии, что суперкласс расширяет тот же класс, что и подкласс.

6 и 7 должны быть очевидны.

4 работает, потому что если мы знаем, что V расширяет K, то мы знаем, что V расширяет Number (поскольку все классы, которые K расширяет V, расширяются). Поэтому мы можем заменить A<V> на <K extends Number>.

Надеюсь, в этом есть смысл ... кто-то может прийти и объяснить лучше.

0 голосов
/ 26 мая 2010

Кажется, работает только второй (public abstract A useMe(A k);), просто подключив его к IDE.

...