• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

Question related Typecasting in Generics

 
Ranch Hand
Posts: 1376
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi

I have one question regarding generics

Following are some code samples

Code Sample A

List<Number> list1 = null;
List<Integer> list2 = null;
list1 = list2;


Code Sample B

List<Number> list1 = null;
List<Integer> list2 = null;
list2 = list1;


Code Sample C

List<? extends Number> list1 = null;
List<Integer> list2 = null;
list1 = list2;


Code Sample D

List<Number> list1 = null;
List<? super Integer> list2 = null;
list1 = list2;


Code Sample E

List<Number> list1 = null;
List<? super Integer> list2 = null;
list2 = list1;


Code Sample A , B , D gives compilation error

Code Sample C , E do not gives compilation error

I would like to know the underlying fundamental conecpt on the basis of which above mentioned code samples are behaving

Please help

Thanks
 
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Code Sample A

& Code Sample B

Both give incompatible type - compile time error.

Reason:
Here no wildcard <?> is being used. So only the type specified will be valid. e.g. only a List<Integer> can be assigned to List<Integer> and nothing else. Neither subtype nor supertype.

=================
Code Sample C

It works because list1 has wildcard(bounded) and Integer extends Number.


Code Sample D

It doesn't work because list1 doesn't have any wildcard being used so only the specified type can be applied. (same reason as in code A & B)

============
Code Sample E

It works on similar lines as Code sample C - list2 has wildcard and Number is supertype of Integer.
 
Abhay Agarwal
Ranch Hand
Posts: 1376
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for your reply

I got your point

thanks
 
Ranch Hand
Posts: 488
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Awesome answer Giffy, that clears up a lot for me as well.
 
Shashank Rudra
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
thanks Brian
 
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi folks,

I am getting confused in generics.. read many tutorial and K &B chapter as well but still struggling . I am taking SCJP mock tests, scoring 80% plus in all sections but generic score is always 40 to 50%.

can someone please explain that why one works and other does not

The below code compiles fine
NavigableSet<? super Object> set = new TreeSet<Object>();
set.add(new Object());


The below code does not compile

NavigableSet<? extends Object> set = new TreeSet<Object>();
set.add(new Object());
 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

reji singh wrote:
The below code does not compile

NavigableSet<? extends Object> set = new TreeSet<Object>();
set.add(new Object());


When you are doing set.add(new Object()) the only thing the compiler knows is that set is a NavigableSet<? extends Object> reference, and the addition operation will break the collection type guarantee sometimes. To see that, try this:

NavigableSet<? extends Object> set = new TreeSet<String>(); // Valid declaration and initialization
set.add(new Object()); // This is a problem, adding an Object to a collection of String

However, when you use a NavigableSet<? super X> reference, you can add X elements to it with no problem, because you are guaranteed that the actual collection object is of type X or a supertype of X, so adding a X element is OK.
 
reji singh
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ruben Soto wrote:

reji singh wrote:
The below code does not compile

NavigableSet<? extends Object> set = new TreeSet<Object>();
set.add(new Object());


When you are doing set.add(new Object()) the only thing the compiler knows is that set is a NavigableSet<? extends Object> reference, and the addition operation will break the collection type guarantee sometimes. To see that, try this:

NavigableSet<? extends Object> set = new TreeSet<String>(); // Valid declaration and initialization
set.add(new Object()); // This is a problem, adding an Object to a collection of String

However, when you use a NavigableSet<? super X> reference, you can add X elements to it with no problem, because you are guaranteed that the actual collection object is of type X or a supertype of X, so adding a X element is OK.



Thanks Ruben, i still feel that I am not clear . Ok, consider this.

NavigableSet<? extends Object> set = new TreeSet<String>();//declaration same as per your comment
set.add("string");// why this is not ok as we are adding string to collection os strings , isnt it?

NavigableSet<? super Object> set2 = new TreeSet<Object>();
set2.add( "string");// NavigableSet<? super Object> --- here the actual collection object is String which is not supertype of X- Object. So, why is it allowed?

NavigableSet<? super String> set2 = new TreeSet<Object>();
set2.add( "string");//allowed as valid
set2.add ( new Object());/// but why its not allowed as Object is supertype of String?--- applying rule --- NavigableSet<? super X> reference, you can add X elements to it with no problem, because you are guaranteed that the actual collection object is of type X or a supertype of X, so adding a X element is OK
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

reji singh wrote:

Thanks Ruben, i still feel that I am not clear . Ok, consider this.

NavigableSet<? extends Object> set = new TreeSet<String>();//declaration same as per your comment
set.add("string");// why this is not ok as we are adding string to collection os strings , isnt it?

NavigableSet<? super Object> set2 = new TreeSet<Object>();
set2.add( "string");// NavigableSet<? super Object> --- here the actual collection object is String which is not supertype of X- Object. So, why is it allowed?


Reji, look at this:

NavigableSet<? extends Object> set; // This is what the compiler looks at (just the reference type.)
set = new TreeSet<String>(); // The actual object could be a collection of String
set = new TreeSet<Integer>(); // Or it could be a collection of Integer, or any other class

The compiler doesn't know the actual type, so it can't let you add anything, because no matter what you add, you could break type safety. For example, if the actual type is a TreeSet<Integer> and you add a String, you have a problem.

However, NavigableSet<? super Object> can only point to a set which holds Object references (since Object doesn't have any supertypes.) Therefore, you can add an element of any type, since every object (no matter of what class) is ultimately an instance of Object.

If you had NavigableSet<? super Integer>, you would have three possibilities:
1. The actual object is a set of Integer references.
2. The actual object is a set of Number references (since Number is a supertype of Integer.)
3. The actual object is a set of Object references (since Object is a supertype of Integer.)

No matter which type out of the possible three the collection actually holds, you can add an Integer. You can add an Integer to a set of Integer references (trivial.) You can also add an Integer to a set of either Number references or Object references, because an Integer object Is-A Number and an Integer object Is-An Object.

Hopefully that will make things clear.
 
reji singh
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ruben,

Many thanks. Its very clear now. I was not able to connect all these things together to have a bigger picture. Hopefully, I will score better now in mocks and will apply the concepts in a better way at work.

Thanks you!
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

reji singh wrote:Hi Ruben,

Many thanks. Its very clear now. I was not able to connect all these things together to have a bigger picture. Hopefully, I will score better now in mocks and will apply the concepts in a better way at work.

Thanks you!


Reji,

I'm glad things make more sense now. Continue practicing, and good luck!
 
Shashank Rudra
Ranch Hand
Posts: 131
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Very good fellows. Here just I would like to re-iterate one concept from K&B

When you have wildcard being used as <? extends Object> - you are saying to compiler that any thing that extends Object will be a valid entry but here I also pledge not to add any thing to the collection. As soon as you try to breach this contract Compiler will squawk.

In case of <? super Object> you are not making any NO-INTENTION-TO-ADD_ANYTHING contract with compiler so thing go as intended.
 
Abhay Agarwal
Ranch Hand
Posts: 1376
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi reji

you can follow "get and put" principle while dealing with wildcards

Thanks
 
reji singh
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
HI Abhay,

What is that principle...?
 
Abhay Agarwal
Ranch Hand
Posts: 1376
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Hi reji

you can follow below mentioned links for more details

http://www.objectdefinitions.com/odblog/2009/confusion-over-lower-bound-wildcards-how-to-apply-the-get-and-put-principle/

http://www.ibm.com/developerworks/java/library/j-jtp07018.html

Thanks

 
reply
    Bookmark Topic Watch Topic
  • New Topic