Возможно ли создание экземпляра List‹T› с универсальным типом?

Студент, которого я обучаю, посещает занятия по веб-разработке, в которых используется книга Dietel по Java, в которой содержится любопытный фрагмент кода, связанный с дженериками:

class StackComposition <T>
{
    private List<T> stackList;

    public StackComposition()
    {
        stackList = new List<T>("stack")  // ERROR
    }

    // .... more code
}

Мне очевидно, почему этот код не работает, и я недоумеваю, почему преподаватель рекомендует ученику использовать этот код в качестве отправной точки. Может быть, я просто не понимаю Generics, и мои навыки Java недостаточны, но я не понимаю, как можно создать экземпляр универсальной коллекции с помощью универсального типа. Я вижу, что цель состоит в том, чтобы создать стек с помощью универсальной коллекции List и определения типа во время выполнения, но я не понимаю, как это возможно с использованием приведенной выше конфигурации. Моей первой мыслью было предложить студенту использовать объект Generic Stack<T> и забыть о написании этого пользовательского класса Stack, но, очевидно, это не является целью задания.

Я попытался в качестве теста использовать пакет java.lang.reflect, чтобы обойти это, но, насколько я могу судить, это работает только с неуниверсальными контейнерами, такими как Array:

public StackComposition(Class<T> type)
{
    Object obj = Array.newInstance(type, 10);
}

person dtg    schedule 27.02.2013    source источник
comment
Как насчет stackList = new ArrayList<T>()?   -  person Luiggi Mendoza    schedule 28.02.2013
comment
stackList = new List<T>("stack") если вы имеете в виду java.util.List, вполне очевидно, почему эта строка не скомпилируется. потому что List - это интерфейс, и вы не можете его создать.   -  person PermGenError    schedule 28.02.2013
comment
во-вторых, снова увидев ваше заявление. я думаю, что List - это пользовательский тип, поскольку any List implementing sub-types не имеет constructor, который принимает String в качестве аргумента   -  person PermGenError    schedule 28.02.2013
comment
@PremGenError предполагает, что вы правы, тогда проблема в реализации класса some.weird.package.List, а не в представленном коде.   -  person Luiggi Mendoza    schedule 28.02.2013
comment
@LuiggiMendoza я тоже не вижу java.util.List импорта. давайте подождем, пока ОП прояснит это .. :)   -  person PermGenError    schedule 28.02.2013
comment
@PremGenError обычно мало кто копирует/вставляет код стены, включая импорт пакетов. Тем не менее, я думаю, что это java.util.List, поскольку OP хотел инициализировать массив с помощью отражения (что становится более странным решением).   -  person Luiggi Mendoza    schedule 28.02.2013
comment
Вы оба правы. Я включил java.util.List и пытался создать экземпляр абстрактного класса List<T>. (Я все время забываю, что C# и Java — это, по сути, разные языки). Это может быть просто ошибка со стороны автора, или, возможно, они определили свой собственный класс List (наиболее вероятный случай).   -  person dtg    schedule 28.02.2013


Ответы (2)


В вашем коде две проблемы:

Вы пытаетесь создать интерфейс с недопустимым ключевым словом new. Вместо этого вы должны создавать экземпляр объекта ArrayList (или класса, который реализует List).

Во-вторых, вам не разрешено передавать ссылку String конструктору.

Итак, вот что вы должны использовать в своем коде:

stackList = new ArrayList<T>();

или stackList = new ArrayList<T>(10);, если вы хотите указать начальный размер для вашего stackList (замените 10 на размер, с которым вы хотите, чтобы ваш список был инициализирован).

person Community    schedule 27.02.2013
comment
Спасибо. Ранее в книге я обнаружил, что автор действительно использовал свой собственный класс List. Но в своем примере кода для вышеизложенного они использовали свой собственный пакет. Это должно было быть подсказкой для меня - person dtg; 28.02.2013

С чисто учебной точки зрения это упражнение могло быть предназначено для иллюстрации композиции путем перенаправления определенных методов на содержащийся экземпляр некоторого более общего типа. Необходимо отображать только нужные методы, а конкретный тип, используемый внутри, можно изменить по мере необходимости.

import java.util.Deque;
import java.util.LinkedList;

public class MyStack<T> {

    private Deque<T> deque = new LinkedList<T>();

    public void push(T item){
        deque.push(item);
    }

    public T pop() {
        return deque.pop();
    }

    public static void main(String[] args) {
        MyStack<Integer> stack = new MyStack<>();
        stack.push(42); // OK
        stack.addFirst(0); // no such method
    }
}
person trashgod    schedule 28.02.2013