aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generics - return types 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 "Generics - return types" Watch "Generics - return types" New topic
Author

Generics - return types

Lakuma Yalamanchili
Greenhorn

Joined: Sep 24, 2008
Posts: 26
Hi,

Let's say we have a return type to a method -> List<E super Number>

Now, where all can this be stored, like when returned by the method:
A. <Any subtype of List><Any super type of Number>
B. <Any subtype of List><Number>

And with this as the return type to a method -> List<E extends Number>
A. <Any subtype of List><Any sub type of Number>
B. <Any subtype of List><Number>

I wonder if either of those options are right, because Generics says it is rigid with what is in between <> as it has to be exactly the same. So either of the options is wrong?

Please let me know which of those two in each of the case is right and also if there are any other possibilities of storing the returned value.

Also, are there real good articles about Generics and polymorphism other than the chapter in K&B. The chapter in K&B on Generics seems real good, but I somehow feel reading more examples would help...any suggestions?

Thanks in advance,
Lakuma
Venkata Saraswathi
Ranch Hand

Joined: Sep 27, 2008
Posts: 55
Is it possible to use 'super' with Generic type?
Ashish Hareet
Ranch Hand

Joined: Jul 14, 2001
Posts: 375
I answered a similar question on one of our forums, see if it helps

Generics & super

Also check out Sun's resource on generics - http://java.sun.com/docs/books/tutorial/java/generics/index.html

HTH
Ashish Hareet
Lakuma Yalamanchili
Greenhorn

Joined: Sep 24, 2008
Posts: 26
Venkata,

Yes there is a section in Chapter 7 - K&B about using super with Generics.

Ashish,

Thanks for the link, it seems to be good to go. So i'll just confirm what I get from this, please correct me if I've misunderstood it!!

Note that by saying <? super Number> we're not saying super classes of Number(as defined for the class), we're saying any & all subclasses of Number. Think of it as simply List.


So <? super Number> indicates any class that has Number as it's super class or Number itself!

<? extends Number> indicates any class that extends Number or Number itself!

What is the difference between the two statements then?? Any class that has Number as it's super class is the same as any class that extends Number, is it not?

If they are the same then why is it that we have two different ways of showing the same thing? Is there a subtle difference to this?

And yes - "Nothing lower in the inheritance tree can come in, but anything higher than Number is OK" is an incorrect statement.


Maybe there is a different meaning to this statement - not the way we are comprehending it - something more than that?

If what is said in the first statement is true:

<? super Number> we're not saying super classes of Number(as defined for the class), we're saying any & all subclasses of Number


Then in the following code, class Animals should not be accepted, but it happens to work, where Animals is a super class of Dog!

Code source - K&B : Chapter 7: Generic Methods Section


Thanks again!!

Regards,
Lakuma
[ October 03, 2008: Message edited by: Lakuma Yalamanchili ]
denis sorn
Ranch Hand

Joined: Apr 30, 2008
Posts: 33
Originally posted by Lakuma Yalamanchili:
Venkata,
So <? super Number> indicates any class that has Number as it's super class or Number itself!

<? extends Number> indicates any class that extends Number or Number itself!


Revrse it. From sun's docu:


Cage<? extends Animal> someCage = ...;
Read "? extends Animal" as "an unknown type that is a subtype of Animal, possibly Animal itself", which boils down to "some kind of animal". This is an example of a bounded wildcard, where Animal forms the upper bound of the expected type. If you're asked for a cage that simply holds some kind of animal, you're free to provide a lion cage or a butterfly cage.
Note: It's also possible to specify a lower bound by using the super keyword instead of extends. The code <? super Animal>, therefore, would be read as "an unknown type that is a supertype of Animal, possibly Animal itself". You can also specify an unknown type with an unbounded wilcard, which simply looks like <?>. An unbounded wildcard is essentially the same as saying <? extends Object>.
Lakuma Yalamanchili
Greenhorn

Joined: Sep 24, 2008
Posts: 26
Thanks Denis!

So I was right when I thought the following is wrong??

<? super Number> we're not saying super classes of Number(as defined for the class), we're saying any & all subclasses of Number


Regards,
Lakuma
[ October 03, 2008: Message edited by: Lakuma Yalamanchili ]
denis sorn
Ranch Hand

Joined: Apr 30, 2008
Posts: 33
I would say so...
Ashish Hareet
Ranch Hand

Joined: Jul 14, 2001
Posts: 375
Originally posted by Lakuma Yalamanchili:

So I was right when I thought the following is wrong??

[ October 03, 2008: Message edited by: Lakuma Yalamanchili ]


I'll disagree, my statement was given in the context of what can be added to the list & not the type of the list in which case it is correct(except that Number should also be included). Denis' statement was from Sun's website & refer's to the type of the list itself, not the type of objects that can be added to the list. Note the distinction in the context of the statements.

Here's some code to see what can/cannot be added to generic lists & how the types of the list themselves affect their usage.



Commented lines cause compile-time errors, refer to Sun's link previously provided to understand why.

HTH
Ashish Hareet
[ October 03, 2008: Message edited by: Ashish Hareet ]
Venkata Saraswathi
Ranch Hand

Joined: Sep 27, 2008
Posts: 55
In the above context is there any difference between these two declarations? If not, why do we go for generic(?) declaration.

List<Animal1> animals1 = new ArrayList<Animal1>();
List<? super Animal1> animals3 = new ArrayList();


Venkata,
Yes there is a section in Chapter 7 - K&B about using super with Generics


can anyone give me an example which uses generic type in this fashion 'List<E super Number>' (not like 'List<? super Number>').
I am not able to compile such declarations.

Thanks in advance.

[ October 04, 2008: Message edited by: Venkata Saraswathi ]
[ October 04, 2008: Message edited by: Venkata Saraswathi ]
sannuth kashikar
Greenhorn

Joined: Sep 16, 2008
Posts: 14
Hi,
Its important to know where wildcard with extends or super to be used.
Wildcard with extends
code:
interface Collection<E> {
...
public boolean addAll(Collection<? extends E> c);
...
}

and
// # 1
List<Number> nums = new ArrayList<Number>();
List<Integer> ints = Arrays.asList(1, 2);
List<Double> dbls = Arrays.asList(2.78, 3.14);
nums.addAll(ints);
nums.addAll(dbls);

The first call is permitted because nums has type List<Number>, which is a subtype of Collection<Number>, and ints has type List<Integer>, which is a subtype of Collection<? extends Number>. The second call is similarly permitted. In both calls, E is taken to be Number.So we use ? extends E

We can also use wildcards when declaring variables. #1 changed by adding a wildcard to the second line:

List<Integer> ints = Arrays.asList(1,2);
List<? extends Number> nums = ints;// ok
nums.add(3.14); //compile-time error because you cannot add
//a double to List<? extends Number>, since
//it might be a list of some other subtype of number
assert ints.toString().equals("[1, 2, 3.14]"); //here is why compile-time error

If a structure contains elements with a type of the form ? extends E, we can get elements out of the structure, but we cannot put elements into the structure.

Wildcards with super

Here is a method that copies into a destination list all of the elements from a source list, from the convenience class Collections:

public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}

? super T means that the destination list may have elements of any type that is a supertype of T, just as the source list may have elements of any type that is a subtype of T.

Here is a sample call.

List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
List<Integer> ints = Arrays.asList(5, 6);
Collections.copy(objs, ints);
assert objs.toString().equals("[5, 6, four]");

As with any generic method, the type parameter may be inferred or may be given explicitly. In this case, there are four possible choices, all of which type-check and all of which have the same effect:

Collections.copy(objs, ints);
Collections.<Object>copy(objs, ints);
Collections.<Number>copy(objs, ints);
Collections.<Integer>copy(objs, ints);



The first call leaves the type parameter implicit; it is taken to be Integer, since that is the most specific choice that works. In the third line, the type parameter T is taken to be Number. The call is permitted because objs has type List<Object>, which is a subtype of List<? super Number> (since Object is a supertype of Number, as required by the super) and ints has type List<Integer>, which is a subtype of List<? extends Number> (since Integer is a subtype of Number, as required by the extends wildcard).

We could also declare the method with several possible signatures.

public static <T> void copy(List<T> dst, List<T> src)
public static <T> void copy(List<T> dst, List<? extends T> src)
public static <T> void copy(List<? super T> dst, List<T> src)
public static <T> void copy(List<? super T> dst, List<? extends T> src)

The first of these is too restrictive, as it only permits calls when the destination and source have exactly the same type. The remaining three are equivalent for calls that use implicit type parameters, but differ for explicit type parameters. For the example calls above, the second signature works only when the type parameter is Object, the third signature works only when the type parameter is Integer, and the last signature works (as we have seen) for all three type parametersi.e., Object, Number, and Integer. Always use wildcards where you can in a signature, since this permits the widest range of calls.

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 get and put.

I think this may help you.
[ October 04, 2008: Message edited by: sannuth kashikar ]

scjp5 90%
suresh pilakal babu
Ranch Hand

Joined: Jul 01, 2008
Posts: 31
import java.util.*;

class Species
{
}
class Animal extends Species {}

class Dog extends Animal{}

class X{

public static void method1(List<? super Animal> animals){
}

public static void method2(List<? extends Animal> animals){
}

public static void method3(List<Animal> animals){
}



public static void main(String[] args){
List<Animal> animals1 = new ArrayList<Animal>();//this list can accept Animal & it's subtypes
List<? extends Animal> animals2 = new ArrayList();
List<? super Animal> animals3 = new ArrayList();

animals1.add(new Dog());
animals2.add(new Species()); //why getting compile- error here.

}
}
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Generics - return types