Win a copy of Escape Velocity: Better Metrics for Agile Teams this week in the Agile and Other Processes forum!
  • 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
  • Liutauras Vilda
  • Tim Cooke
  • Paul Clapham
  • Jeanne Boyarsky
Sheriffs:
  • Ron McLeod
  • Frank Carver
  • Junilu Lacar
Saloon Keepers:
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Al Hobbs
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • fred rosenberger

Generics on JavaBeat's mock exam

 
Ranch Hand
Posts: 329
Oracle Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I got puzzled by the following mock question from JavaBeat:


which are all valid method(s) inserted independently will allow program to compile

a) public Object get() { ... }
b) public Long get() { ... }
c) public void set(Object arg) { ... }
d) public void set(Long arg) { ... }
e) public Number get() { ... }

The answer given was: b, d and e, but I thought it should be b, c, d and e.
I tried it out and, in fact, the compiler (javac) told me that there was an error. This is the code I tried:

and the error I got:


JBeat.java:6: name clash: set(java.lang.Object) in Child and set(E) in Parent<java.lang.Number> have the same erasure, yet neither overrides the other
class Child extends Parent<Number>
^
1 error



The message is very strange: shouldn't get() method's (in parent's class ) erasure be something like:


Then I tried changing the code to:

with almost the same error:


JBeat.java:6: name clash: set(java.lang.Object) in Child and set(Number) in Parent<java.lang.Number> have the same erasure, yet neither overrides the other
class Child extends Parent<Number>
^
1 error


This one looks even stranger to me: set(java.lang.Object) in Child and set(Number) in Parent<java.lang.Number> have the same erasure !!!

And for a final try:

but this one, suprisignly, compiles fine.

Does anyone have an idea? What is the logic behind all this?
[ June 22, 2007: Message edited by: Sergio Tridente ]
 
Ranch Hand
Posts: 652
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Sergio,
Look at the below declaration
class Child extends Parent<Number>
{
public void set(Object arg) { }
}

The type E will be either the type of Number or sub-class of Number and since Object is super class of Number you are getting the error.

class Parent<E>
{
public E get() { return null;}
public void set(E e) { }
}
class Child extends Parent<Object>
{
public void set(Object arg) { }
}

but this one, suprisignly, compiles fine.

Reason is same here the type E can be of type Object or subclass of type Object.


Regards
Nik
 
Ranch Hand
Posts: 377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I think Sergio's problem is that it works without generics.

 
Sergio Tridente
Ranch Hand
Posts: 329
Oracle Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Manfred Klug:
I think Sergio's problem is that it works without generics.



Yes, you are right. That's what seems very strange to me, specially in the second example where I am not using E for the argument type of the set() method.


Originally posted by nik arora:
The type E will be either the type of Number or sub-class of Number and since Object is super class of Number you are getting the error.



Well, in the first example (which is same as the original question) I was expecting the void set(Object arg) method in Child to overload the void set(E e) in Parent<E>, 'cause (at least this is what I understand) the erasure for that method should be void set(Number e) for Parent<Number> class.
[ June 22, 2007: Message edited by: Sergio Tridente ]
 
Sergio Tridente
Ranch Hand
Posts: 329
Oracle Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK. Now another candidate for the "weirdest java thing" award:



This works!!!

Even this one works:



I am getting the impression that javac does not handle Generics very well. I will try all examples in Eclipse to see if it makes any difference.


[EDIT]
It gets even better. Take a look at this one:

It does not compile giving the following message:


JBeat.java:11: set(java.lang.Number) in Parent<java.lang.Number> cannot be applied to (java.lang.Object)
public void set() { super.set(new Object()); }
^
1 error


Which, if I understand it correctly, means that the erasure of void get(E e) in Parent<E> is not void get(Object) but void get(Number) (what I always suspected).
[ June 22, 2007: Message edited by: Sergio Tridente ]
 
Ranch Hand
Posts: 2412
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think what's confusing you is the fact that entities in different namespaces can have the same name without a compile-time error.

That is, when you have this as a class definition,

,

Number is a type parameter, and is NOT java.lang.Number.
 
Sergio Tridente
Ranch Hand
Posts: 329
Oracle Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Keith Lynn:
Number is a type parameter, and is NOT java.lang.Number.



Yes. You are right! Thank you.

Now it is clearer. This one works:




But one question remains. Why doesn't this one work?
 
Keith Lynn
Ranch Hand
Posts: 2412
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You are extending Parent<Number> which means that to override set, you need to make the argument Number. Generics are implemented through type erasure, and that prevents you from placing set(Object) in the subclass since it has the same erasure as set(E) from the parent class, but it's not overriding the method from the superclass since it's parameter is Number, and the parameter in the subclass is Object.

If you make either of these changes, the code will compile.



 
Sergio Tridente
Ranch Hand
Posts: 329
Oracle Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Keith. It is clearer now.
 
We're being followed by intergalactic spies! Quick! Take this tiny ad!
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic