3

Lets say I have the class :

class Box<T>{}

Now what is the difference between :

public myMethod(Box box){};

and

public myMethod(Box<?> box){};

Update:

I'm asking because I want to see the effect on the variable box, Is the variable identical in both cases or not.

Jimmy
  • 10,427
  • 18
  • 67
  • 122
  • 1
    Read this: http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html – Konstantin Yovkov Aug 27 '13 at 17:41
  • 2
    Those docs do not answer his question. – David Williams Aug 27 '13 at 17:42
  • 2
    possible duplicate of [What is a raw type and why shouldn't we use it?](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) – Paul Bellora Aug 27 '13 at 17:43
  • I think this question is about raw types, not the wildcard as super to all types concept. – David Williams Aug 27 '13 at 17:44
  • I updated the question. Its not about when should I use the raw type, its about if there any effect on the parameter if I want to use it inside the method (is the two objects will be identical or did they have different informations about their type) – Jimmy Aug 27 '13 at 18:04

2 Answers2

3

Collection<?> (pronounced "collection of unknown"), that is, a collection whose element type matches anything.

I am not sure about your Box class definition so it is hard to describe it from that. But if you use any collection such as List, Map, Set. Then you can define the type of objects it may contain using generics. So if the type is not defined then it means you are allowing the raw types in your colection as mentioned here

Collection c;

But if you want this collection to store only a particular type then you can specify it using generfic. For examlple a collection of String:

Collection<String> c;

But if you want to allow any type of object to be stored then you use collection of unknown, as defined here:

Collection<?> c;

Using generics, allow you to find problems during compile time.

Read more here: http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
  • 2
    This doesn't explain what plain `Box` means, or the difference between it and `Box>`. – Paul Bellora Aug 27 '13 at 17:44
  • See update, I'm more concern about the effect on the parameter inside the method. – Jimmy Aug 27 '13 at 18:02
  • @Jimmy There is actually no difference because in both the cases you are allowing any type of elements in your Box collection. – Juned Ahsan Aug 27 '13 at 18:03
  • 1
    @Jimmy There is a difference. A `Box>` will not accept any input except `null`, since it's type is unknown (read about PECS). A `Box` will accept anything, and it's up to the caller to cast responsibly. – Paul Bellora Aug 27 '13 at 18:46
  • It bewilders me why 10k+ users decide to post lackluster answers instead of voting to close as duplicates of obvious and excellently answered posts - oh wait, points, nevermind. – Paul Bellora Aug 27 '13 at 18:46
  • @PaulBellora Not sure what you meant by *will not accept any input except null*, but if you try myMethod(new Box()) it will work for both cases. – Jimmy Aug 27 '13 at 18:53
  • 1
    @Jimmy I'm saying that if `Box` has a method `put(T item)`, then `put(someObject)` correctly won't compile with a `Box>`, because `someOject` can't be guaranteed to be the unknown type that `?` represents. Read about PECS. – Paul Bellora Aug 27 '13 at 20:14
3

Generics have been introduced into Java to help you catch a wide range of bugs in compile-time, instead of just encountering ClassCastException at runtime.

When you use <?> (a wildcard) you are saying to the compiler that you don't know (or don't care about) the generic type. For example: if you just want to count the number of elements of an Iterable<?>, you simply don't care about the types of the elements, so you could create a method with the signature int countElements(Iterable<?> iterable), that would simply retrieve an Iterator<?> from the iterable (note the wildcard type again), and then just call hasNext() and next(), while incrementing a counter.

You could do the same without the <?>, which is what is called a raw type.

You should almost never use raw types. Raw types are allowed since Java tries to be as backwards compatible as possible. If they didn't allow you to use raw types, almost all Java code from versions before 1.5 (when Generics have been introduced) would have to be rewritten; the raw types allows the compiler to compile that code -- although it will issue warnings.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
Bruno Reis
  • 37,201
  • 11
  • 119
  • 156