2013-04-17 5 views
1

У меня есть функция f, которая получает подсписок в LinkedList и передает его g, который также принимает LinkedList:SubList LinkedList возвращает список вместо LinkedList?

public static <T> void g(LinkedList<T> l) { 
} 

public static <T> void f() { 
    LinkedList<T> l = new LinkedList<T>(); 
    ... 
    LinkedList<T> l2 = l.subList(i,j); 
    ... 
    g(l2); 
} 

Но это не компилируется, потому что очевидно LinkedList.subList возвращается List вместо LinkedList. Поэтому я должен изменить его на это:

LinkedList<T> l2 = (LinkedList<T>)l.subList(i,j); 

Почему?

+0

Программирование на интерфейсы, а не реализации. –

ответ

5

subList определен в интерфейсе List и возвращает List. И если вы проверите реализацию в LinkedList, которая фактически находится в одном из родительских классов (AbstractList), вы увидите, что она не возвращает LinkedList, а SubList, и ваш бросок будет выдавать исключение.

Если вы не используете методы, специфичные для LinkedList, самый простой способ, чтобы исправить это было бы изменить g на:

public static <T> void g(List<T> l) { 
+0

Хорошо сказано mate..sublist() из списка, а не из LinkedList – Chandu

+0

, к сожалению, 'g' требует' LinkedList'. – Dog

+0

Вы всегда можете вызвать 'g (новый LinkedList (подсписок));' ... – assylias

0

, если г() не использует метод LinkedList, но только интерфейс List является предпочтительно, чтобы определить г() следующим образом:

public static <T> void g(List<T> l) { 
} 

и главным становится:

public static <T> void f() { 
    List<T> l = new LinkedList<T>(); 
    ... 
    List<T> l2 = l.subList(i,j); 
    ... 
    g(l2); 
} 

Для обоснования, please consult this post.

-1

Java хочет столько полиморфизма, сколько вы можете получить, поэтому subList возвращает List, и вы должны отдать его тому, что хотите.

+0

Фактически, он возвращает 'java.util.SubList', чтобы вы не могли отбросить его, как хотите! 'java.lang.ClassCastException: java.util.SubList нельзя передать в java.util.LinkedList' –

0

Метод sublist указан в интерфейсе List, который реализован LinkedList. Сигнатура метода sublist в интерфейсе List является:

List<E> subList(int fromIndex, int toIndex) 

Таким образом, всякий раз, когда вы вызываете этот метод из LinkedList класса, объект будет иметь LinkedList, но тип возвращаемого метода является List, таким образом, это будет дано в виде List. Однако вы можете переместить переменную в LinkedList и использовать ее.

0

Вы не можете создать экземпляр «Список объектов». Список - это интерфейс, а не конкретный класс. Интерфейс - это всего лишь набор функций, которые может реализовать класс; нет смысла создавать интерфейс.

Надеюсь, это поможет.

Clemencio Morales Lucas.