Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Overriding rule for generics 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 "Overriding rule for generics" Watch "Overriding rule for generics" New topic
Author

Overriding rule for generics

prashanth kumar
Ranch Hand

Joined: Mar 22, 2004
Posts: 162
Hello Ranchers,
It looks like overriding rule for generics is different than normal overrriding rules


The above code compains that its not a valid override

But the below code works fine and accepts as a normal override.




Any reasons??

Many Thanks
Prashanth


SCJP1.5(86%)<br />SCWCD1.4(95%)<br />SCBCD1.3(92%)<br />IBM 252
Costa lamona
Ranch Hand

Joined: Sep 24, 2006
Posts: 102
It is not overriding rules
boolean add(E o) this is the declaration of add method in the
ArrayList API doc

so the argument type is generic, and you must override it with a generic like this


or
Matching superclass Type like this



maybe this is not every thing.
but Take Care the following code is legal


output is
Object....
String....

and this is overloading not overriding, and this is not allowed with generics because compiler is not sure about what will be the generic type.


SCJP 5
Keith Lynn
Ranch Hand

Joined: Feb 07, 2005
Posts: 2367
Notice that in the definition of ArrayList<E>, the method signature of add is add(E o).

Try it like this.

prashanth kumar
Ranch Hand

Joined: Mar 22, 2004
Posts: 162
Originally posted by prashanth kumar:
Hello Ranchers,
It looks like overriding rule for generics is different than normal overrriding rules


The above code compains that its not a valid override

But the below code works fine and accepts as a normal override.




Any reasons??

Many Thanks
Prashanth



Sorry..
I got bit confused..
What i intended was why is the Following code not a legal Overload

Thanks Again

Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Hi Prashanth,


if you say:
class BookList extends ArrayList<Country> { ...

then BookList is no longer a generic type.
For example it wouldn't compile if you said:
BookList<Country> = new BookList<Country>();

And everything that was of type Object in ArrayList now becomes the non-generic-and-just-as-in-old-days-fixed-type Country.
So the type for the override has also to be Country (not Object, and no subtype).


The following would compile:









Your second example
class BookList extends ArrayList { ...

you have also a non-generic extension.
But here you have Object as fixed type, so this behaves as a Collection in Java 1.4 and overriding the add method with object is fine.



Yours,
Bu.


all events occur in real time
Costa lamona
Ranch Hand

Joined: Sep 24, 2006
Posts: 102
Originally posted by prashanth kumar:



Sorry..
I got bit confused..
What i intended was why is the Following code not a legal Overload

Thanks Again



Look I am not sure , and I did not read it in any specifications but I have this Theory that Compiler is telling me something like this

Hi this is Mr. Compiler of java5, I have read your code, and I decide to refuse it because I am a java phelosopher, and I have this rule-->
"I enforce good coding, not just allowing it"

In your code it is not obvious that you are doing overloading because you are overloading a generic type (which happened to be assigned to Country)
and this is means that It could be Country, India, Egypt, Dog, Cat, ElAdawi, Prashanth, AboAmr, any thing including Object, Ooops, but a class of type Object will make your method overriding not overloading, and this is which make it not obvious thing,

imagine that some programmer just look into the middle of your class API

1- He knows that ArrayList is generic
2- He found two add methods
3- He is wonderring which one is overloading and which is
overridng.

4- Ask your self what might happen if it is anynomous class or you have
zillion classes extending ArrayList, each with different type.

yes it is legal, but not obvious, so for your best interest I will avoid you from doing that, and I will lie and say it is not legal, because I am your friend man.

But take care


This is not legal too, because Object is still not obvious overloading
someone could be mistaken.

but this is ok


It make a sense !!, Isn't it?
Burkhard Hassel
Ranch Hand

Joined: Aug 25, 2006
Posts: 1274
Hi ranchers,

the last but one example of Mohammed does not compile...

... because of something the compiler calls:
Name clash:
"The method add(Object) of type Booklist has the same erasure as add(E) of type ArrayList<E> but does not override it"

It is neither a legal override nor overload.
Whereas the country-method is a legal override. By inheritance, BookList has already an add(Country) method, also e.g. get(int i) that returns a Country.

When I said in my previous posting, that BookList is no longer generic, I was a bit misleading, sorry.
Behind the scenes, the class is generic, but you cannot make generic instances of it.

You can't say e.g.
BookList<India> ilist= new BookList<India>();
The compiler would say something like:
The type BookList is not generic; it cannot be parameterized with arguments <India>

But the class is in a way generic as for example it has the method
addAll(Collection <? extends Country> c)

Mohammed is right when he says:
I have this Theory that Compiler is telling me something like this

Hi this is Mr. Compiler of java5, I have read your code, and I decide to refuse it (...)


So, generic classes could be extended the way it is done here, but then you have the fixed type (Country) and cannot go back to object any longer.


Yours,
Bu.
Costa lamona
Ranch Hand

Joined: Sep 24, 2006
Posts: 102
Originally posted by Burkhard Hassel:
Hi ranchers,

the last but one example of Mohammed does not compile...


It no need to be the last, We are all getting fun here, so don't worry, specialy that generics is not trivial thing.

Actually I was telling that this code will not compile

Originally posted by Mohammed EL-Adawi:
[QB]

But take care


This is not legal too, because Object is still not obvious overloading
someone could be mistaken.

Abdul Rehman
Ranch Hand

Joined: Nov 07, 2006
Posts: 65
Originally posted by Burkhard Hassel:

the last but one example of Mohammed does not compile...

(Code skipped...)

... because of something the compiler calls:
Name clash:
"The method add(Object) of type Booklist has the same erasure as add(E) of type ArrayList<E> but does not override it"

This is described in the JLS 3rd Ed. in Chapter 8, "Classes." I reproduce here an extract from Section 8.4.8.3:-

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

It is a compile time error if a type declaration T has a member method m1 and there exists a method m2 declared in T or a supertype of T such that all of the following conditions hold:
  • m1 and m2 have the same name.
  • m2 is accessible from T.
  • The signature of m1 is not a subsignature (�8.4.2) of the signature of m2.
  • m1 or some method m1 overrides (directly or indirectly) has the same erasure as m2 or some method m2 overrides (directly or indirectly).

  • Discussion
    These restrictions are necessary because generics are implemented via erasure. The rule above implies that methods declared in the same class with the same name must have different erasures. It also implies that a type declaration cannot implement or extend two distinct invocations of the same generic interface. Here are some further examples.

    A class cannot have two member methods with the same name and type erasure.


    This is illegal since D.id(Object) is a member of D, C<String>.id(String) is declared in a supertype of D and:
  • The two methods have the same name, id
  • C<String>.id(String) is accessible to D
  • The signature of D.id(Object) is not a subsignature of that of C<String>.id(String)
  • The two methods have the same erasure.

  • Discussion
    Two different methods of a class may not override methods with the same erasure.



    This is also illegal, since D.id(String) is a member of D, D.id(Integer) is declared in D and:
  • The two methods have the same name, id
  • The two methods have different signatures.
  • D.id(Integer) is accessible to D
  • D.id(String) overrides C<String>.id(String) and D.id(Integer) overrides I.id(Integer) yet the two overridden methods have the same erasure.

  • ----------------------------

    Hope, this will help others in understanding the problem.
    [ November 11, 2006: Message edited by: Abdul Rehman ]

    SCJP 5.0 (100%)
     
    Consider Paul's rocket mass heater.
     
    subject: Overriding rule for generics