2013-04-27 10 views
10

Dlaczego specyfikacja JVM stwierdza, że ​​interfejsy muszą mieć super_class z java/lang/Object, mimo że interfejsy nie rozszerzają się na java/lang/Object?Dlaczego interfejsy rozszerzają obiekt, zgodnie z formatem pliku klasy?

mam konkretnie odnoszące się do §4.1 spec JVM, gdzie jest napisane:

Dla interfejsu, wartość przedmiotu super_class zawsze musi być ważny wskaźnik do tablicy constant_pool. Pozycja constant_pool w tym indeksie musi być strukturą CONSTANT_Class_info reprezentującą obiekt klasy.

jeszcze w §9.2 z JLS, mówi, że interfejsy nie rozszerzają Object. Zamiast tego domyślnie tworzony sposób abstrakcyjny deklaruje, który pasuje każdej metody publicznej w klasie Object:

Jeśli interfejs ma bezpośrednie superinterfaces, następnie interfejs niejawnie deklaruje public abstract metoda członek mz podpis s, zwracany typ R i podaje klauzulę t odpowiadającą każdej metodzie publicznej m z podpisem s, typowi powrotu r oraz klauzuli throws t zadeklarowanej w Object, chyba że metoda z tym samym podpisem, tym samym typem zwracania i zgodną klauzulą ​​throws jest jawnie deklarowana przez berło.

Odpowiedz

7

Jak wspomniano §9.2:

Jeżeli interfejs ma bezpośrednie superinterfaces, to interfejs pośrednio deklaruje publicznego streszczenie metody element m podpis s, typu powrotnym R i wyrzuca klauzuli t odpowiadającej każdej publicznej metodzie instancji m z sygnaturą s, typem powrotu r oraz klauzulą ​​rzutów t zadeklarowaną w Object, chyba że metoda z tym samym podpisem, ten sam typ zwracania i zgodna klauzula rzutowania jest jawnie zadeklarowana przez interfejs.

Stąd widzimy, że chociaż interfejs nie mając bezpośredniego superinterface wyraźnie nie rozciąga Object ale nadal ma ona związek z Object klasy wewnętrznie, ponieważ jest wykorzystywany przez kompilator do wstawienia metody abstrakcyjne z tym samym podpisem i typ zwrotny i klauzula throws jako metody publiczne w klasie Object w interfejsie. Dlatego dla interfejsu wartość elementu super_class musi zawsze być prawidłowym indeksem w tabeli constant_pool. Pozycja constant_pool w tym indeksie musi być strukturą CONSTANT_Class_info reprezentującą klasę Obiekt. Z tego powodu zmienna referencyjna interfejsu może z powodzeniem wywoływać publiczne metody instancji, na przykład metodę toString() z Object. Na przykład, rozważmy kod podany poniżej:

interface MyInterface 
{} 
public class InterfaceTest implements MyInterface 
{ 
    public static void main(String[] args) 
    { 
     MyInterface mInterface = new InterfaceTest(); 
     System.out.println(mInterface.toString());//Compiles successfully. Although toString() is not declared within MyInterface 
    } 
} 

Powyższy kod kompiluje pomyślnie mimo toString() metody (co jest metoda Object) nie jest zgłaszany w ramach MyInterface. Powyższy kod podaje następujące dane wyjściowe w moim systemie:

[email protected] 

Dane wyjściowe mogą się różnić w zależności od systemu.

0

To, co widzisz w specyfikacji JVM, to w zasadzie konkretna implementacja zachowania określonego przez JLS - tak jak klasy implementują interfejsy i mają szczegóły implementacji.

Powiązane problemy