Что означает List в Java generics?

Что значит List<?> означает ли это просто список объектов неопределенного типа?

Googling для строки <?> возвращает ничего полезного (:

8 ответов


ключевое слово, необходимое для получения дополнительной информации, -Шаблоны


Как сказал том,?, или групповой символ, означает, что тип объекта не указан. Это может быть неизвестно, может быть предназначено для нескольких возможных значений или может быть просто неуместным. Ваш пример,List<?>, произносится как " список неизвестных."Это удобно, потому что это гибкий, но есть и некоторые подводные камни, потому что вы не можете засунуть случайные объекты и вытащить их из групп неизвестных с total безнаказанность.

ресурсы:

  • Шаблоны обсуждаются здесь в учебнике Java.
  • есть хороший-если многословный-учебник по дженерикам в целом по Angelika Langer доступен здесь.
  • и есть еще один хороший обзор здесь (PDF) Гилада Брача; проверьте страницы 5-7.
  • наконец, если вы можете получить ваши руки на Эффективная Java Джош блох, у него есть большой раздел о дженериках и случаях, в которых вы можете, не можете, должны и не должны использовать подстановочные знаки (Глава 5, страницы 109-146 во втором издании).

Кстати, Ваш поиск Google не удался, потому что Google не работает со специальными символами:

за некоторыми исключениями пунктуация игнорируется (то есть вы не можете искать @#$%^&*()=+[]\ и другие специальные символы).

-справка Google страница

(EDIT: я, должно быть, очень устал, когда писал Это прошлой ночью. Очистил форматирование / добавил немного информации.)


Похоже, вы должны искать некоторую документацию по Java generics.

на List<?> означает, что это объект, основанный на неопределенном в данный момент типе. Что применяется при создании экземпляра класса.

например:

List<String> listOfStrings = new ArrayList<String>();

- это список строковых объектов.


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

1. Неограниченные Шаблоны

неограниченный тип подстановочного знака задается с помощью подстановочного знака (?), например, List<?>. Это называется списком неизвестного типа. Существует два сценария, в которых неограниченный подстановочный знак является полезным подходом:

  • если вы пишете метод, который может быть реализован с использованием функциональных возможностей, предоставляемых в классе Object.

  • когда код использует методы в общем классе, которые не зависят от параметра type. Например, List.size или List.clear. На самом деле,Class<?> так часто используется, потому что большинство методов в Class<T> не зависит от T.

2. Ограниченные Подстановочные Знаки

рассмотрим простое приложение для рисования, которое может рисовать фигуры, такие как прямоугольники и круги. Для представления этих фигур в программе можно определить иерархию классов, например:

public abstract class Shape {
    public abstract void draw(Canvas c);
}

public class Circle extends Shape {
    private int x, y, radius;
    public void draw(Canvas c) {
        ...
    }
}

public class Rectangle extends Shape {
    private int x, y, width, height;
    public void draw(Canvas c) {
        ...
    }
}

эти классы можно нарисовать на холсте:

public class Canvas {
    public void draw(Shape s) {
        s.draw(this);
   }
}

любой чертеж обычно содержит несколько фигур. Предполагая, что они представлены в виде списка, было бы удобно иметь метод в Canvas, который рисует им всем:

public void drawAll(List<Shape> shapes) {
    for (Shape s: shapes) {
        s.draw(this);
   }
}

теперь правила типа говорят, что drawAll() может вызываться только в списках точной формы: он не может, например, вызываться на List<Circle>. Это неудачно, так как все, что делает метод, - это чтение фигур из списка, поэтому его можно также вызвать на List<Circle>. Мы действительно хотим, чтобы метод принимал список любой формы: public void drawAll(список фигур) { ... } Есть небольшой, но очень важное отличие здесь: мы заменили тип List<Shape> С List<? extends Shape>. Теперь drawAll() будет принимать списки любого подкласса Shape, так что теперь мы можем назвать его List<Circle> если мы хотим.

List<? extends Shape> является примером ограниченного подстановочного знака. The ? означает неизвестный тип, однако в этом случае мы знаем, что этот неизвестный тип на самом деле является подтипом формы. (Примечание: это может быть сама форма или какой-то подкласс; ему не нужно буквально расширять форму.) Мы говорим, что форма верхний предел подстановки.

аналогично, синтаксис ? super T, который является ограниченным подстановочным знаком, обозначает неизвестный тип, который является супертипом T. А ArrayedHeap280<? super Integer>, например,ArrayedHeap280<Integer>, ArrayedHeap280<Number> и ArrayedHeap280<Object>. Как вы можете видеть в документация java для целого класса, Integer-подкласс числа, который, в свою очередь, является подклассом объекта.


List - это интерфейс, который вы можете реализовать самостоятельно, а также реализован некоторыми коллекциями Java, например Vector.

вы можете предоставить информацию о времени компиляции, используя угловые скобки. Самый общий тип будет Object, которые будут List<Object>. The <?> вы видите, указывает список некоторых подклассов Object или Object. Это все равно что сказать List<? extends Object> или List<? extends Foo>, где List содержит объекты некоторого подкласса Foo или объекты .

вы не можете создать экземпляр List; это интерфейс, а не реализация.


List<?> расшифровывается как List<? extends Object> так Collection<E> вы найдете containsAll(Collection<?> c) что позволяет писать

List<Object> objs = Arrays.<Object>asList("one",2,3.14,4);
List<Integer> ints = Arrays.asList(2,4);
assert objs.containsAll(ints);//true

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

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

chk dis pdf


вы, вероятно, смотрите на основе шаблона List класса. Вы можете создать список строк с List<String> myList = new MyList<String>(); в качестве примера. Проверьте документацию для всех типов, которые она поддерживает. Он должен поддерживать любой тип объекта, но если есть функциональность сортировки, вы должны предоставить некоторые функции сравнения.

обратите внимание, что в приведенном выше примере MyList - это конкретный класс, реализующий List интерфейс на Java. Это может быть ArrayList.

изменить: Я предположил List Как a конкретный класс по ошибке. Исправлена ошибка выше. Спасибо, Джон.