Каковы «веские» причины использовать <?> В Java Generics? - PullRequest
2 голосов
/ 19 февраля 2012

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

У меня есть дизайн, где такой класс:

Class World<T, C> { .... }

определенно делает мой код чище, чем без дженериков.

Тем не менее, иногда я использую

World theWorld;

или иногда я получаю

World<?, ?> theWorld;

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

Это выглядит уродливым и вонючим для меня, и все же я не могу оправдать добавленную сложность, которую я должен представить, чтобы ее избежать.

В каких случаях (если таковые имеются) вы полагаете, что использование обнаженного или подстановочного универсального кода является приемлемой идиоматической Java?

Ответы [ 3 ]

4 голосов
/ 19 февраля 2012

Есть хороший пример (вариант использования) использования <?> в разделе Подстановочные знаки учебного пособия Generics.

Сортировка: если вы хотите написать метод printCollection, который принимает все виды Collection, вы можете использовать Collection<?> в качестве типа параметра.Вы не можете использовать Collection<Object> в качестве типа параметра для этой цели, поскольку он не является супертипом всех видов коллекций.

Использование Collection<?> вместо «чистого» * ​​1013 * в этом случае безопаснее, поскольку выневозможно добавить элементы в Collection<?> (кроме нуля) в методе printCollection.

3 голосов
/ 19 февраля 2012

Каждый раз, когда вы можете использовать дженерики, но не нужно в данной конкретной ситуации.<?> примерно говорит компилятору: «Я знаю об обобщениях, но мне сейчас не нужен тип».

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

Пахнет, если вы используете слишком слабо связанные параметры типа (например, <?>, что довольно свободно), но пытаетесь определить тип впоследствии, например, с помощью instanceof или какой-то пользовательский дискриминатор типов.Тогда что-то было спроектировано плохо.

1 голос
/ 19 февраля 2012

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

Например:

Collection<? extends Shape> myShapes

Эта коллекция теперь может хранить все объекты, которые являются подклассом Shape. Таким образом, вы безопасны при добавлении любого объекта, который является подклассом Shape. Например:

myShapes.add(new Rectangle())
myShapes.add(new Triangle())
...