88

I have read O'Reilly book, in that I came to know this get-put principle.

  • Use an extends wildcard when you only get values out of a structure.
  • Use a super wildcard when you only put values into a structure.
  • And don't use a wildcard when you both want to get and put from/to a structure.

Exceptions are:

  • You cannot put anything into a type declared with an extends wildcard except for the value null, which belongs to every reference type.

  • You cannot get anything out from a type declared with an super wildcard except for a value of type Object, which is a super type of every reference type.

Can anyone help me to explore this rule at depth? If possible, please put them hierarchical manner.

nbro
  • 15,395
  • 32
  • 113
  • 196
JavaResp
  • 2,253
  • 5
  • 24
  • 25

1 Answers1

178

Consider a bunch of bananas. This is a Collection<? extends Fruit> in that it's a collection of a particular kind of fruit - but you don't know (from that declaration) what kind of fruit it's a collection of. You can get an item from it and know it will definitely be a fruit, but you can't add to it - you might be trying to add an apple to a bunch of bananas, which would definitely be wrong. You can add null to it, as that will be a valid value for any kind of fruit.

Now consider a fruitbowl. This is a Collection<? super Banana>, in that it's a collection of some type "greater than" Banana (for instance, Collection<Fruit> or Collection<TropicalFruit>). You can definitely add a banana to this, but if you fetch an item from the bowl you don't know what you'll get - it may well not be a banana. All you know for sure is that it will be a valid (possibly null) Object reference.

(In general, for Java generics questions, the Java Generics FAQ is an excellent resource which contains the answer to almost anything generics-related you're likely to throw at it.)

nbro
  • 15,395
  • 32
  • 113
  • 196
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • but while fetching a fruit from Collection, you may get any fruit not the banana. similarly,while putting a fruit to it,u may add any thing which may not belong to banana fruits – JavaResp Aug 18 '09 at 06:49
  • 6
    Java will prevent you from adding anything other than null to a `Collection extends Fruit>` for exactly that reason, and you'd have to explicitly cast the result of fetching an item, for precisely those reasons. – Jon Skeet Aug 18 '09 at 07:00
  • @JonSkeet This might be a stupid question, but in what cases is it useful not to have "access" to both add() and get() methods? I mean, to get() some object out of a list, you have to add it first, right? And vica versa, why would you add it if you cannot get it afterwards? – Timmos Jan 17 '13 at 16:37
  • 7
    @Timmos: Just because *something* has to be able to add a value doesn't mean that *all* code needs to be able to. For example, in order to display a list of person names, I may just need a `Collection extends Person>` (or more probably just an `Iterable extends Person>`, but...). The code *creating* that collection may well need it to be a `Collection`, but the *consuming* code doesn't. – Jon Skeet Jan 17 '13 at 16:40
  • @JonSkeet OK I understand. So it is some kind of protection? – Timmos Jan 17 '13 at 16:46
  • 5
    @Timmos: You'd have to say *exactly* what you meant by "it" in this case... but yes, the rules of Java generics are designed to provide type safety. – Jon Skeet Jan 17 '13 at 16:57
  • @JonSkeet This doesn't really make sense to me. Why can I do: `MyType myObject (MyType) object;` and even `T t; MyType myObject = (MyType)(Object)t;` but not `MyType myObject = (MyType) t;` – Philip Whitehouse Nov 13 '14 at 14:45
  • @PhilipWhitehouse: It's not clear to me what your comment has to do with this answer... perhaps you should ask a new question giving details of your concerns? – Jon Skeet Nov 13 '14 at 15:23