• 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:
  • Tim Cooke
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Rob Spoor
  • Bear Bibeault
Saloon Keepers:
  • Jesse Silverman
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Piet Souris
  • Al Hobbs
  • salvin francis

One more Generics Question

 
Ranch Hand
Posts: 103
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Excuse me - if it too obvious or silly.

Why does below doesn't compile?

When we say, new TreeSet<Object>(), the treeset is typed to take in any object right?

The compiler says the method add(capture#1-of ?) in the type TreeSet<capture#1-of ?> is not applicable for the arguments (Object)

I don't seem to be getting it at all!

Regards,

Muthaiah
 
Ranch Hand
Posts: 317
Eclipse IDE
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wherever is <?> in collection initialization, you can not add anything to List. Except one case where you are using super keyword like <? super someClass>

This is not same as List<Object>, because here you are specifying a particular class that can be added to this collection but <?> means this list can refer a collection of any type. Because the compiler will not be sure about the type so we can not perform add operation on this collection.



 
Ranch Hand
Posts: 142
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey, it is a valid question and it does confuse a lot of people.

The simple answer is that Generics in java only provide "compile time safety" and not run-time safety. This is because of what is called as "Type Erasure" i.e. After java compiles the code, it removes the Generic type information from the bytecode and the run-time code is non-generic. The add operation is considered unsafe during run-time.

Please read my answer that explains this in a posting with a similar question in this link. It is the last message in that thread. Hope it helps. If not I will be glad to explain it to you further.

If you read the above link good. But let me explain it a little bit further:

<?> provides polymorphic generic reference types. By that what I mean is:

Set<?> q1 = new TreeSet<Object>(); is valid
Set<?> q1 = new TreeSet<String>(); is also valid
Set<?> q1 = new TreeSet<Integer>(); is also valid

You can basically substitute any type within the <> on the right hand side, since you have <?> (a wild card reference) on the left hand side. But as I told all the above types are only applicable during compile time i.e. this is how the code looks at compile time. After the code is compiled, java does "TYPE ERASURE" and to the JVM all of the above code only looks like the one shown below i.e. without any type information. It doesn't really matter what type you had declared on the right hand side. It is all erased. This is the most critical concept you have to burn into your mind Hence all of the above code for the JVM will look like below without any type information:

Set<?> q1 = new TreeSet();

So the problem is the JVM doesn't know that you intended this list to be a collection of Object types or String types or Integer types or any other types. So at run-time when you try to add an entry to the list, the JVM cannot prevent you from mistakingly or intentionally adding any object type you want, since again the JVM doesn't know what type of objects you intented the list to contain - due to TYPE ERASURE. For example if the compiler had allowed you to do the add() operation, then it means you will be able to do:

Set<?> q1 = new TreeSet<String>();
q1.add(new Integer());

which is invalid, because now you are mistakingly adding a Integer type to a String collection and the JVM can't prevent you from doing that if the compiler had allowed the add operation to begin with. So this is considered unsafe at run-time. Because of that, they designed the compiler not to allow the add operation which is unsafe.

Does that make it clear? Again the points to remember are:

- Generics types are only applicable during compile time
- Type erasure is done after compilation and the type information is not available to the JVM
- add operation is considered unsafe because if it is allowed the JVM can't prevent you from adding an object type that doesn't belong to the collection. Hence the compiler won't allow it.

Hope this helps you to understand the concept.
 
Ranch Hand
Posts: 423
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

consider this example - assume add() is allowed and compiles fine:

How do you think, what happens in line 5 ?
.....
And because this can happen, compiler prevents to add elements to collections of unknown <?> type.


There is another problem with this code - elements of treeset are expected to implement Comparable interface,
ie. they must implement compareTo( obj, obj ) method - treeset uses this method to compare objects in the tree.
Object type doesn't implement COmparable.
 
Ranch Hand
Posts: 182
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I think we have the same question in Devaka's ExamLabs final exam (Question number 24) with greater explanation.

Above explanations + we are free to add null values in to it.
 
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic