aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generic Problem Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Generic Problem" Watch "Generic Problem" New topic
Author

Generic Problem

Mohit G Gupta
Ranch Hand

Joined: May 18, 2010
Posts: 634

Nikos Blog

Problem-1

compile time error:
name clash: say(java.util.List<java.lang.Integer>) in Child and say(java.util.List<? extends java.lang.Number>) in Parent have the same erasure, yet neither overrides the other
class Child extends Parent {
^
1 error


i cannot understand what this error say's.even if use the commented line,the error still comes.




this works fine ...

why error in the first code ?




----------------------------------------------------------------------------------
Problem-2


why i cannot add object to this Treeset ?


OCPJP 6.0 93%
OCPJWCD 5.0 98%
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4422
    
    8

For problem 2, imaging changing the first line to this:
Now, would you expect the second line to work? But the reference type of set is just the same.

The compiler will prevent you adding, because it can't guarantee the add will be safe.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4422
    
    8

For the first problem, remember that generics don't exist at run-time, only at compile time. The information is thrown away once the compiler is sure it's OK. This is called type erasure.

So List<? extends Number> and List<Integer> both resolve to List in the compiled code. So both Parent and Child effectively have a method void say(List list). That's what "have the same erasure" means.

Now, this would be fine if the second one overrode the first one. But it can't do that, because they have different generic types. The sub-class is being more strict than the superclass. And that would break the substitution principle. Overriding is therefore impossible, which is what the second part of the error means.

Mohit G Gupta
Ranch Hand

Joined: May 18, 2010
Posts: 634

mathhew ,thanks

but

if i change the code

problem-1


This code compiles fine.
why there is no error in this code ??

------------------------------------------

problem-2

But it can't do that, because they have different generic types. The sub-class is being more strict than the superclass. And that would break the substitution principle. Overriding is therefore impossible, which is what the second part of the error means.


if generics don't exist at run-time, only at compile time.then it should easily allow overriding


and

how is

The sub-class is being more strict than the superclass.
Piotr Nowicki
Ranch Hand

Joined: Jul 13, 2010
Posts: 610

If it comes to



remember, that it is equal to:



And - as with all generics "extends" - compiler prevents you from adding anything to the collection.


OCP Java SE 6 Programmer, OCM Java SE 6 Developer, OCE Java EE 6 JSPSD, OCE Java EE 6 EJBD, OCE Java EE 6 JPAD, Spring 3.0 Core Professional.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4422
    
    8

(Splitting my answer into two messages to keep it neater)
mohitkumar gupta wrote:
if i change the code

Here you're mixing generic and non-generic collections, which is always a bad idea and can lead to problems. Because of the need to make new generic code work with existing non-generic code a few concessions are made. But basically, unless you've got no choice, don't do it.
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4422
    
    8

mohitkumar gupta wrote:
if generics don't exist at run-time, only at compile time.then it should easily allow overriding

and how is The sub-class is being more strict than the superclass.

Because generics don't exist at run time, the compiler has to be very strict and prevent anything that might not be valid.

Consider this code, if the compiler allowed overriding like that:
All OK. But now change the line to:
This should still work: according to the Liskov substitution principle we should be able to use a Child whenever a Parent is needed. But now we've just violated the generic contract on Child.say.

That's what I mean by being more strict. Parent will allow List<Number>, List<Integer>, List<Double> etc as arguments. Child only allows List<Integer>. The compiler won't let you do that. And the compiler is your friend .
 
Consider Paul's rocket mass heater.
 
subject: Generic Problem