czwartek, 13 listopada 2008

Name clash: has the same erasure but does not override it

Pisząc aplikacje wykorzystujące generyki, możecie natrafić na przedziwny błąd. Wyobraźcie sobie interfejs IDao (z pojedyncza metoda updateStubs(List<T>) oraz klasę, która go implementuje AbstractDao. I nagle kompilator krzyczy:

Name clash: The method updateStubs(List) of type AbstractDao<T> has the same erasure as updateStubs(List) of type IDao but does not override it.


Zaraz zaraz, metoda z klasy ma taką samantykę i erasure jak nadrzędna metoda z interfejsu, ale jej nie nadpisuje? O co chodzi?
Spójrzmy na początek definicji interfejsu:


public interface IDao<T extends IStub> {


a następnie na początek defnicji klasy AbstractDao:


public abstract class AbstractDao<T extends IStub> implements IDao {


Co jest nie tak? Otóż wprawna osoba odrazu zauważy (a nieroztropny [czytaj ja] programista przegapi) fakt, iż przy IDao brakuje odwołania do typu generycznego! Poprawnie powyższa definicja powinna wyglądać następująco:


public abstract class AbstractDao<T extends IStub> implements IDao<T> {


Po tej małej zmianie wszystko powino być już w porządku, a kompilator nie krzyczy, że ma metode w podklasie, ale jej nie nadpisze.

1 komentarz:

Koziołek pisze...

Pozwolę sobie na podrzucenia linka do dość dużego FAQ (około 500 stron w pdfie) o genericsach:
Java Generics FAQs autorstwa Angeliki Langer.
Pozdrawiam