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 doubt ? 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 doubt ?" Watch "Generics doubt ?" New topic
Author

Generics doubt ?

Ashok Pradhan
Ranch Hand

Joined: Dec 17, 2007
Posts: 180



Anyone please explain me Why I cannot add Cat to the list
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9313
    
  17

Since the list is of type <? extends Animal>, so it can be any animal. It can be a Dog, a human or a Cat. So the compiler wont allow you to add anything to this list. You cannot add anything to this list by any means(of course you can do that by using legacy code).


SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
Ashok Pradhan
Ranch Hand

Joined: Dec 17, 2007
Posts: 180

Thanks Ankit,Is that mean as it is a type safe code:-

List<? extends Animal> list = new ArrayList<Cat>();

so the compiler does not allow it:-

Since the list is of type <? extends Animal>, so it can be any animal. It can be a Dog, a human or a Cat. So the compiler wont allow you to add anything to this list.
Bob Ruth
Ranch Hand

Joined: Jun 04, 2007
Posts: 320
The way that i see that: The reference variable is declared as

List<? extends Animal> list

and your code assigns a new ArrayList<Cat>() to it.

it is true that list is currently set to a "Cat" object but the compiler has to behave as though, at "run time" any type of List implementing obejct COULD BE assigned to list that matches the type specified ( <Dog>, <Cat>, <Bird> ). Because of that, the compiler must allow List to accept any of those types (including Animal) but the only way that the compiler can guarantee type safety is to prohibit adding anything at all to the collection.


------------------------
Bob
SCJP - 86% - June 11, 2009
suresh pilakal babu
Ranch Hand

Joined: Jul 01, 2008
Posts: 31
Hi,

i am not able understand
what does it "List<? extends Animal> list = new ArrayList<Cat>();" mean.
What I learnt from this is "list can contain any Animal or subtype of Animal." In that sense the statement "list.add(new Cat());" is correct.rt?

Please clarify me.
Bob Ruth
Ranch Hand

Joined: Jun 04, 2007
Posts: 320
Not quite Suresh, a fine point:

list can not hold an animal or subclass of animal,
rather,
it can hold a LIST OF animal or subclass of animal.

You see list is of type List so it can hold a reference to a container that implements the List interface. The generic type specification
<? extends Animal> says that whatever container list points to can CONTAIN Animal or a subclass of Animal. That said, you can assign a reference to ArrayList<Animal>, Vector<Dog>, or LinkedList<Cat> to the reference variable "list".

Where the problem comes in.... the compiler has to think very generally when it compiles your code. It is true that your specific code is assigning a new ArrayList<Cat> to list. The compiler does not assume that this will be the only thing stored in list at run-time. It has to be prepared to accept ANY type that the generic type says. And THAT could be any of <Animal>, <Dog>, <Cat>, or any other subclass of Animal. Since the compile has no way to know which generic types might be assigned to list, the only way that it can guarantee type safety, is to prohibit any additions to references specified as <? extends ClassName>. If list ever got assigned an ArrayList<Dog> you would not want to add a Cat to it. Since the run-time environment (JVM) has no way to check/limit the type of Object added at run time, the compiler must do the type enforcement itself and the only way that it can do that is to forbid you from adding anything to it.

Note that: if List were List<? super Animal> the add would work. THAT generic type guarantees that whatever List is assigned WILL be of a type that will at least hold Animal and, if it can hold Animal then it can hold any subclass of Animal, so the compiler will allow that.

Read this and think about it and see if it looks a little more clear.
chander shivdasani
Ranch Hand

Joined: Oct 09, 2007
Posts: 206

One point to remember,
When ever you use the keyword "extends", you cannot use add().
This is why,

The main reason why Generics came into exsistence was to provide Type security at compile time.


void test (List<? extends Animal> { add(new Dog() }

Consider the above function, and lets call it using

test(ArrayList<Cat>

Now,what is happening is, you are assigning a List<? extends Animal> with
ArrayList<Cat> and adding a Dog object into an ArrayList that should contain Cat Objects.

There is no way a compiler can tell what you are adding, so to prevent these kind of things from happening, it does not allow you to add anything.


Enjoy, Chander
SCJP 5, Oracle Certified PL/SQL Developer
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Generics doubt ?