Что означает List<?>
, означает ли это просто список объектов неопределенного типа?
Googling для строки <?>
не возвращает ничего полезного (:
Что означает List<?>
, означает ли это просто список объектов неопределенного типа?
Googling для строки <?>
не возвращает ничего полезного (:
Ключевое слово, необходимое для получения дополнительной информации, Wildcards
Как сказал Том, ?
или неограниченный подстановочный знак означает, что тип объекта не указан. Это может быть неизвестно, может быть рассчитано на несколько возможных значений или может быть просто неуместным. Ваш пример, List<?>
, произносится как "Список неизвестных". Это удобно, потому что оно гибкое, но есть и некоторые подводные камни, потому что вы не можете засунуть случайные объекты и вытащить их из групп неизвестных с полной безнаказанностью.
Ресурсы
Кстати, ваш поиск Google не удался, потому что Google не вывоз со специальными символами:
За некоторыми исключениями пунктуация игнорируется (т.е. вы не можете искать @# $% ^ & *() = + []\и другие специальные символы).
(EDIT: Я, должно быть, очень устал, когда писал это вчера вечером. Убрал форматирование/добавил немного информации.)
Чтобы ответить на этот вопрос, мне нужно объяснить неограниченные символы и ограниченные символы.
Содержание этого поста было собрано из документации Java.
Неограниченный подстановочный тип указывается с использованием подстановочного знака (
?
), например,List<?>
. Это называется списком неизвестного типа. Существует два сценария, в которых неограниченный подстановочный знак является полезным подходом:
Если вы пишете метод, который может быть реализован с использованием функций, предоставляемых в классе Object.
Когда код использует методы в общем классе, которые не зависят от параметра типа. Например,
List.size
илиList.clear
. На самом деле,Class<?>
так часто используется, потому что большинство методов вClass<T>
не зависят отT
.
Рассмотрим простое приложение для рисования, которое может рисовать фигуры, такие как прямоangularьники и круги. Чтобы представить эти фигуры в программе, вы можете определить иерархию классов, например:
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()
можно вызывать только в списках точно Shape: его нельзя, например, вызывать вList<Circle>
. Это прискорбно, так как все, что делает метод - это считывает фигуры из списка, поэтому его можно также вызывать дляList<Circle>
. Что нам действительно нужно, так это чтобы метод принимал список любой формы: public void drawAll (Список фигур) { ... } Здесь есть небольшое, но очень важное отличие: мы заменили типList<Shape>
наList<? extends Shape>
. ТеперьdrawAll()
будет принимать списки любого подклассаShape
, поэтому теперь мы можем вызвать его наList<Circle>
, если захотим.
List<? extends Shape>
является примером ограниченного символа подстановки.?
обозначает неизвестный тип, однако в этом случае мы знаем, что этот неизвестный тип фактически является подтипом Shape. (Примечание. Это может быть сам Shape или некоторый подкласс; ему не нужно буквально расширять Shape.) Мы говорим, что Shape является верхней границей подстановочного знака.
Точно так же синтаксис ? super T
, который является ограниченным подстановочным знаком, обозначает неизвестный тип, который является супертипом T.
ArrayedHeap280<? super Integer>
, например, включает в себя ArrayedHeap280<Integer>
, ArrayedHeap280<Number>
и ArrayedHeap280<Object>
.
Как вы можете видеть в документации Java для класса Integer, Integer является подклассом Number, который, в свою очередь, является подклассом Object.
Похоже, вы должны искать документацию по генеалогическим файлам Java.
List<?>
означает, что это объект, основанный на текущем неуказанном типе. Эта спецификация создается при создании экземпляра класса.
Например:
List<String> listOfStrings = new ArrayList<String>();
- список объектов String.
List
- это интерфейс, который вы можете реализовать самостоятельно, а также реализован некоторыми наборами Java, например Vector
.
Вы можете предоставить информацию о времени компиляции, используя угловые скобки. Наиболее общим типом будет Object
, который будет List<Object>
. <?>
, который вы видите, указывает список некоторых подклассов Object
или Object
. Это как сказать List<? extends Object>
или List<? extends Foo>
, где List
содержит объекты некоторого подкласса Foo
или объекты самого 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 предоставляет вам способ передать тип коллекции компилятору, чтобы его можно было проверить. После того, как компилятор знает тип элемента коллекции, компилятор может проверить, что вы использовали коллекцию последовательно и можете вставить правильные отбрасывания на значения, извлекаемые из коллекции.
? не что иное, как Wildcard в Generics
В Generics есть 3 разных вида символов подстановки
1) Подстановочные знаки с верхним ограничением: используется расширяет ключевое слово
eg: List<? extends SuperClass>
2) Подстановочные знаки с нижним ограничением
eg:Uses Super key word List<? super SubClass>
3) Неограниченный шаблон
List<?> list
Вероятно, вы ищете шаблон на основе List
. Вы можете создать список строк List<String> myList = new MyList<String>();
в качестве примера. Проверьте документацию на все типы, которые она поддерживает. Он должен поддерживать любой тип объекта, но если есть функция сортировки, вы должны предоставить некоторые функции сравнения.
Обратите внимание, что в приведенном выше примере MyList
- это конкретный класс, реализующий интерфейс List
в Java. Это может быть ArrayList
.
EDIT:
Я предположил List
как конкретный класс по ошибке. Исправлена ошибка выше. Спасибо, Джон.