2009-03-24 14 views
5

Mam następujący kod:Nie można uczynić statycznych odniesienie do ogólnych podklasy (Java)

class SuperClass { 
    public static String getName() { return "super"; } 
} 

class SubClass extends SuperClass { 
    public static String getName() { return "sub"; } 
} 

public class Dummy<T extends SuperClass> { 
    public void print() { 
     System.out.println("SuperClass: " + SuperClass.getName()); 
     System.out.println("SubClass: " + SubClass.getName()); 
     System.out.println("T: " + T.getName()); 
    } 
    public static void main(String[] args) { 
     new Dummy<SubClass>().print(); 
    } 
} 

Ten kod generuje następujące:

SuperClass: super 
SubClass: sub 
T: super 

Moje pytanie brzmi: Dlaczego nie T .getName() zwraca wartość SubClass.getName()? W końcu określiłem, że T == SubClass. Czy też statyczne wywołania funkcji są nieważne dla ogólnych odniesień?

Bardzo dziękuję z góry!

Odpowiedz

13

To nie jest tylko kwestia dotycząca leków generycznych.

Jeśli powiesz:

SuperClass obj = new SubClass(); 
System.out.println(obj.getName()); 

będzie można również uzyskać "super". Nie ma "polimorficznych" metod statycznych.

W twoim przypadku cały kompilator wie o T, że rozszerza SuperClass, więc zadzwoni pod numer SuperClass.getName().

+0

OK, to jasne do tej pory. Ale jak mogę wywołać statyczną metodę SubClass.getName() z Dummy używając T? Chciałbym mieć wiele dalszych podklas, a manekin może wywoływać funkcję getName() w sposób przejrzysty. – JeffreyHammansson

0

Po wprowadzeniu klasy "new Dummy()" wywołałeś domyślny konstruktor, który w rzeczywistości niczego nie ustawił. Po wywołaniu metody drukowania, maszyna wirtualna zobaczyła, że ​​typ T, jak zadeklarowano w deklaracji klasy, to SuperClass; Następnie wywołuje metodę statyczną na tej klasie.

1

przeciwieństwie do C++ szablony, Java leków generycznych pracy przez typ usunięcia, więc to tylko generuje jedną klasę dla wszystkich wartości T i przekłada wszelkie odniesienia do wpisywania T w tej klasie do super rodzaju T, w tym przypadku SuperClass, następnie wykorzystuje wirtualną wysyłkę, aby zapewnić wariancję wywołań dla metod obiektowych i statyczną wysyłkę do wywołań metod statycznych.

Więc kiedy zrobić Dummy<SubClass>.print(), kompilator nie robi globalna zastąpić od T z SubClass w Dummy. Wszystko, co robi kompilator, to sprawdzenie, czy użycie T jako argumentu lub typu zwracanego w metodach Dummy to . Nie ma żadnych zmian w żadnym kodzie wewnątrz Dummy, więc ta sama metoda statyczna SuperClass zostaje wywołana niezależnie od tego, T.

Jeśli chcesz mieć inne zachowanie w klasie ogólnej w zależności od sparametryzowanego typu, musisz przekazać obiekt tego typu i użyć metody wirtualnej lub przekazać klasę dla typu i użyć odbicia.

Powiązane problemy