3

why do we need the pure <?> in Java? Does anything passed can only be used as Object ? So it's the same useful as any class casted to Object (only 9 methods could be available)

Thanks


I mean, if you have List< ? > list, you can only use items as Object. This means list.get(0) gives you Object and nothing more. Yes, also I can store to there anything, but is it useful for you? It's like you have a good an expensive thing and put it to a garbage bin. The only you can get from a trash bin is trash. As well you can put any good object of any class to List but get only Object from there with only 9 methods.

arminvanbuuren
  • 957
  • 1
  • 9
  • 16
  • 1
    Might be helpful https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super – jspcal Jul 20 '18 at 17:39
  • 6
    `List>` is not the same as `List`. It's the same as `List extends Object>` – Michael Jul 20 '18 at 17:45
  • sure, i just wrote "can only be used as Object " and "it's the same useful as any class casted to Object". So any class could be casted to Object as well as the any class can be posted to > – arminvanbuuren Jul 20 '18 at 18:22
  • What do you mean by "anything passed can only be used as Object"? Passed (used?) how/where? Could you post some example which will clarify your question? Possibly while writing such example you will also find answer to your queston... – Pshemo Jul 20 '18 at 18:38
  • 1
    A `List` allows you to `add` **anything** to the `List` as it contains objects. A `List>` does **not** allow you to `add` anything to the `List` as it contains some specific unknown type. The to are very, very different. – Boris the Spider Jul 20 '18 at 18:43
  • I mean, if you have List> list, you can only use items as Object. This means list.get(0) gives you Object and nothing more. Yes, also I can store to there anything, but is it useful for you? It's like you have a good an expensive thing and put it to a garbage bin. The only you can get from a trash bin is trash. As well you can put any good object of any class to List> but get only Object from there with only 9 methods. – arminvanbuuren Jul 21 '18 at 10:47

2 Answers2

6

There are two scenarios where an unbounded wildcard is a useful approach:

  • If you are writing a method that can be implemented using functionality provided in the Object class.

  • When the code is using methods in the generic class that don't depend on the type parameter.
    For example, List.size, or List.clear. In fact, Class<?> is so often used because most of the methods in Class<T> don't depend on T.

For example, see Collections.swap method:

public static void swap(List<?> list, int i, int j) {
    final List l = list;
    l.set(i, l.set(j, l.get(i)));
}

Knowing the type does not aid in swapping two elements within a List,  so an unbounded wildcard is used. You pass in a List - any List - and the method swaps the indexed elements. There is no type parameter to worry about.

For more information, see: Unbounded Wildcards.

Oleksandr Pyrohov
  • 14,685
  • 6
  • 61
  • 90
  • 1
    Your `swap` example is a bit of a dirty hack - it uses a rawtype to fix the wildcard problem. `public static void swap(List list, int i, int j)` would be a better option. – Boris the Spider Jul 20 '18 at 18:45
1

I think the best answer is because sometimes you literally do not know what type a class is parameterized with. As Michael pointed out List<?> is not the same as List<Object>. So ? provides different semantics, which are useful in ensuring program correctness.

Consider two lists. One list is List<String> and the other is List<Integer>. Both of those are Objects, but we still don't want to get them mixed up. We don't want to put a String in the Integer list or vice-versa. So if you have a type declared as List<?>, you cannot safely put any type in that list. The ? could be String or Integer, but you don't know what it is, and you don't want to mix them up, so you can't put either in.

OTOH, List<Object> is just a list of objects, and since you declared it to hold any objects, you can safely put both String and Integer in the list. You said you didn't care what went into the list by declaring it of type Object, so any type is fine. In any meaningful way I can think of, List<Object> is equivalent to a raw type. It's a list that you manage yourself, without help from the compiler.

markspace
  • 10,621
  • 3
  • 25
  • 39