aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generic lower unbound vs upper bounded wildcards Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Generic lower unbound vs upper bounded wildcards" Watch "Generic lower unbound vs upper bounded wildcards" New topic
Author

Generic lower unbound vs upper bounded wildcards

Joey Sanchez
Ranch Hand

Joined: Jun 23, 2011
Posts: 86



The answer for this question tell that when a method takes a wildcard generic typ, the collection can be accessed or modified, but not both. (Kathy and Bert)
What does it mean 'when a method takes a wildcard generic typ, the collection can be accessed or modified, but not both'?

As far as I know,
The method do1 has 'List<? extends Dog> d2' so d2 only can be accessed but not modified.
The method d2 has 'List<? super Collie> c2' so c2 can be accessed and modified and there is no compilation error.

Generic guidelines: http://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html
Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575


you can only access the Dog as in d2.get(i);. you cant set anything into d2, except null.
So you use ? extends Dog to *get* value(Dog) from list

*d2 is a producer list


here you can set objects which is Collie . but you can't get Collie as in c2.get(i); because it returns Object then again you need type casting
So use above idiom, when you need to *set* Collie object

*c2 is consumer.

for more details, Search PECS pattern in generics.

Hope this helps
Himai Minh
Ranch Hand

Joined: Jul 29, 2012
Posts: 734
Hi Joey, refer to this recent post. You can get an answer:

http://www.coderanch.com/t/594481/java-programmer-SCJP/certification/Type-safe-generic-code
Joey Sanchez
Ranch Hand

Joined: Jun 23, 2011
Posts: 86

The answer for this question tell that when a method takes a wildcard generic typ, the collection can be accessed or modified, but not both. (Kathy and Bert)


That's a fair first approximation, but we can say that:

You can not add anything but null (Thanks Henry Wong) to a Collection<? extends Dog> because its add method takes an argument of ? extends Dog. Whenever you invoke a method, you must pass parameters that are of a subtype of the declared parameter type; but for the parameter type ? extends Dog, the compiler can never be sure the argument is of compatible type. However, you can of course modify the collection by calling clear() or remove(Object).

On the other hand, if you read from a Collection<? super Dog>, its iterator has return type ? super Dog. That is, it will return objects that are a subtype of some unknown supertype of Dog. But differently, the Collection could be a Collection<Object> containing only instances of String. Therefore


so the only thing we know is that instances of Object are returned, i.e. the only type-correct way of iterating such a Collection is


but it is possible to read from a collection, you just don't know what types of objects you will get.

We can easily generalize that observation to: Given


and


we can not invoke any methods of G that are declared to take a parameter of type T, but we can invoke methods with return type T, and assign the result a variable of type Something.

On the other hand, for


we can invoke any methods of G that are declared to take parameters of type T, and we can invoke methods with return type T, but only assign the result to a variable of type Object.

To summarize, the restrictions on the use of wildcard types only depend on the form of the method declarations, not on what the methods do.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18715
    
  40

Joey Sanchez wrote:You can not add to a Collection<? extends Dog> because its add method takes an argument of ? extends Dog. Whenever you invoke a method, you must pass parameters that are of a subtype of the declared parameter type; but for the parameter type ? extends Dog, the compiler can never be sure the argument is of compatible type. However, you can of course modify the collection by calling clear() or remove(Object).


Almost, there is one value that the compiler can be sure that it can add(). And that value is null, as it can be assigned to any reference of any type, which includes all types that extend Dog.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
 
jQuery in Action, 2nd edition
 
subject: Generic lower unbound vs upper bounded wildcards