File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generics...please clarify 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...please clarify" Watch "Generics...please clarify" New topic
Author

Generics...please clarify

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.

}
}

Why i m geting compil error "animals2.add(new Species()); "?
[ October 05, 2008: Message edited by: Bear Bibeault ]
Rekha Srinath
Ranch Hand

Joined: Sep 13, 2008
Posts: 178
Suresh,

Its because ? is a wildcard that prohibits you to add elements to a list. Its only a guarantee that you give the compiler that you will not add anything to that list. That is why you get the compiler error when you invoke the add method on that list animals2.
suresh pilakal babu
Ranch Hand

Joined: Jul 01, 2008
Posts: 31
Rekha,
But the line

animals3.add(new Dog());

code is working.
patrick avery
Ranch Hand

Joined: Sep 12, 2008
Posts: 46
I think these are the rules:

List<Animal> animals1 // this list can accept only Animal

List<? extends Animal> animals2 // this list can accept only Animal subtypes

List<? super Animal> animals3 // this list can accept only Animal ancestors

Thanks Pat Avery


SCJA 96%
SCJP 6 88%
skipping SCJD to work on passing SCWCD
suresh pilakal babu
Ranch Hand

Joined: Jul 01, 2008
Posts: 31
Hi Patric,

According to you the below code should work .right?

animals2.add(new Dog());
animals3.add(new Species());

But i am geeting error in both lines.

Thanks,
Suresh.
patrick avery
Ranch Hand

Joined: Sep 12, 2008
Posts: 46
No, you are correct....I think my "rules" were incorrect....I need to go study Generics some nore....

Here is a detailed link that I found.........
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

Thanks, Pat Avery
Rekha Srinath
Ranch Hand

Joined: Sep 13, 2008
Posts: 178
Suresh,

Here are the rules:
? extends - As I said earlier, you cannot add anything to a list declared in this way.
? super - You can add elements, but only of types equal to or more than (higher up the inheritance tree) what follows the super keyword.

So, considering your example,
? extends cannot add anything to the list.
? super can add elements of type Animal or Species (because Species is higher up in the inheritance tree than Animal).
List<Animal> animals1 = new ArrayList<Animal>();//-- This is obvious, you can add only Animal or animal subtypes to the list animals1

As per my understanding, the ? extends construct can be used in a method's parameters where you say the compiler, "I will not add anything to the list being passed in this parameter. But, this function will accept any parameter that is a type or a sub-type of the class passed"

Eg: void Function (List<? extends Animal) -- This function accepts values that is-A animal (Animal itself or subtypes of Animal)

Hope I am clear to you.
suresh pilakal babu
Ranch Hand

Joined: Jul 01, 2008
Posts: 31
Rekha,
Let me summarise my understanding

So, considering your example,
If ? extends -->cannot add anything to the list usind add method.

As per my understanding '? super E' specify upper boundary.
I mean we can add sub types of E or E itself. My statement is contradicting with yours.Which one is correct? Please advics me.


Thanks,
Suresh.
Rekha Srinath
Ranch Hand

Joined: Sep 13, 2008
Posts: 178
Suresh,
If ? extends -->cannot add anything to the list usind add method

Yes, the above statement of yours is true

'? super E' specify upper boundary.
I mean we can add sub types of E or E itself. My statement is contradicting with yours

No, ? super E means you can even ADD to the list, but you can add only E or supertypes of E only. (E and anything higher in the inheritance tree of E)
Mattias Sander
Greenhorn

Joined: Oct 05, 2008
Posts: 1
So, in...

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

I should be able to add Animal and any of its super types. How come I get ann error when trying to add a Species object?

animals3.add(new Species());
Rekha Srinath
Ranch Hand

Joined: Sep 13, 2008
Posts: 178
Oh oh oh...I am having a tough time studying Generics
Here is what I understood...Though not sure if I am correct. Nevertheless, just penning them down...Somebody please correct me if I am wrong.

(1) First of all, the correct statement of assignment is
List<? super Animal> animals3 = new ArrayList<Species>();
ie. The object created also should have a generic type to be assigned to the left hand side reference.
So, the statement List<? super Animal> animals3 = new ArrayList();
is wrong.

(2) So, in the above statement, you say that the generic type of the right hand side object created should satisfy the generic type specified in the <> of left hand side.
In our case, "Species" satisfies the condition "? super Animal", because "? super Animal" accepts anything that IS-A Animal.

(3) This is the tricky part that I am not quite sure of...
While trying to add elements to "animals3" list, I am able to add anything that is lower in the inheritance tree than Animal.
AM I CORRECT HERE?


So, to summarise,
(1) The rule ? super should be applied to what kind of object is created and assigned to the reference.

(2) While adding elements to the list, we are supposed to add those objects that are lower in the inheritance tree or itself, than the generic type given in the left hand side.

Code Eg:
suresh pilakal babu
Ranch Hand

Joined: Jul 01, 2008
Posts: 31
Hi Rekha,

How can you tell the statement
List<? super Animal> animals3 = new ArrayList();
is wrong. Its compiling fine.

I think we almost clarified '? super E'

How about '? extends E'?

Thanks,
Suresh.
Rekha Srinath
Ranch Hand

Joined: Sep 13, 2008
Posts: 178
Yes, List<? super Animal> animals3 = new ArrayList(); compiles fine. But, we are unable to add a Species to it. The moment you include a <Species> on the right hand side of this expression, things change.
Arijit Daripa
Ranch Hand

Joined: Aug 09, 2008
Posts: 142
Originally posted by Rekha Srinath:

? extends - As I said earlier, you cannot add anything to a list declared in this way.


Okay

Originally posted by Rekha Srinath:

? super - You can add elements, but only of types equal to or more than (higher up the inheritance tree) what follows the super keyword.


No,No,No,No
? super - You can add elements, but only of types equal to or lower than what follows the super keyword.


SCJP 5
Ravi Yadav
Greenhorn

Joined: Mar 02, 2008
Posts: 29
Hi,

I was playing around this these super keyword - I am unable to understand why the following piece of code doesnt compile.

import java.util.*;
class species{
}
class Animal extends species{
}
class Dog extends Animal{
}

public class testgeneric{

public static void main(String arg[]){
new testgeneric().fun();
}
public void fun(){

List<? super Animal> an = new ArrayList<species>();
an.add(new species());
}

}

I get an error -
testgeneric.java:24: cannot find symbol
symbol : method add(species)
location: interface java.util.List<capture of ? super Animal>
an.add(new species());
^
1 error

Shouldnt I able to add species to the collection since species is a super class of Animal?

Please advice!!
Vierda Mila
Ranch Hand

Joined: Feb 25, 2008
Posts: 61

List<? super Animal> an = new ArrayList<species>();
an.add(new species());


Hi Ravi,

As per my understanding, here is the explanation :

List <? super Animal> an = new ArrayList <species> ();//you can pass Animal, species and Object in here.

an.add (new species());//here this code will break, because you can only add Animal or its subtype.

Hope it helps

regards,
-Vierda Mila-


SCJP 5
Rekha Srinath
Ranch Hand

Joined: Sep 13, 2008
Posts: 178
Yes, Vierda is perfectly right.

The "super" concept is applicable to the generic type of the list being assigned.

But, the add() method will accept only subtypes or itself of what is in the declaration.

This is the compiler's way of ensuring that you do not add any wrong values to the list. Because, any methods of the supertype can be invoked on the subtype object as well (Polymorphism in play again here, Eg: Even by passing a Dog, you can invoke Animal's method on Dog, but not the other way around).

So, by preventing us to add any supertypes to the list, the compiler ensures type-safety. All this happens during compile time because generics comes into play purely during compilation only.

I had a tough time yesterday and today finding this out :-)
Ravi Yadav
Greenhorn

Joined: Mar 02, 2008
Posts: 29
Thanks for the clarification guys!
aslika bahini
Ranch Hand

Joined: Mar 03, 2007
Posts: 111
Hi Rekha,

Thanks for the URL link.


Orginally posted by Rekha Srinath

The "super" concept is applicable to the generic type of the list being assigned.

But, the add() method will accept only subtypes or itself of what is in the declaration.


According to the rules above the following code should work. But, I am receiving compiler error at line #4. Please explain.




Thank You
Saritha
aslika bahini
Ranch Hand

Joined: Mar 03, 2007
Posts: 111
Hi Rekha,

I am sorry. I have declared class Animals as abstract class
that was the problem.

Thanks
Saritha
Vyas Sanzgiri
Ranch Hand

Joined: Jun 16, 2007
Posts: 686

Oops...this thread was a comedy of errors!


===Vyas Sanzgiri===
My Blog
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Generics...please clarify