2013-07-31 8 views

Odpowiedz

10

Uzyskiwanie dostępu do prywatnych członków z innej klasy jest nieco bardziej skomplikowane, ponieważ wirtualna maszyna języka Java faktycznie na to nie zezwala. W rezultacie kompilator wstrzykuje metody dostępu, które powodują, że jest on nieco wolniejszy, a ślad stosu bardziej skomplikowany.

Z tego powodu pozostawiam go jako pakiet lokalny.

BTW Konstruktor urządzenia abstract class również nie musi być public. Może to być równie dobrze protected lub lokalnego pakietu

private static class A { 
    private A() { 
     throw new Error(); 
    } 
} 
public static void main(String... ignored) { 
    new A(); 
} 

drukuje dodatkowy pierwiastek śladowy stos.

Exception in thread "main" java.lang.Error 
    at Main$A.<init>(Main.java:8) 
    at Main$A.<init>(Main.java:6) 
    at Main.main(Main.java:12) 

Utwórz pakiet konstrukcyjny lokalny, a drugi znika.

+0

Dlaczego tworzona jest dodatkowa linia śledzenia stosu? Jak to działa? Przypomniałem sobie, że dodatkowa linia występuje tylko wtedy, gdy zdefiniuję ją jako prywatną. Tylko dla chronionych dwóch linii. Oznacza to więc, że definiowanie prywatnych spadków wydajności? Dlaczego kompilator JVM umożliwia definiowanie konstruktora takich klas z widocznością> = chroniony? –

+1

@ ŁukaszRzeszotarski JVM nie zezwala na prywatny dostęp z innej klasy. To, co robi javac w celu obejścia tego, to generowanie metod syntetycznych, które nie są prywatne i można je nazwać. Otrzymają numer linii na początku klasy. Wygenerowana metoda wywołuje prawdziwą metodę. Robi to dla wszystkich członków prywatnych. Wolniejszy w trybie interpretacji, po zoptymalizowaniu dodatkowa metoda jest wbudowana i nie ma wpływu AFAIK, z wyjątkiem systemów JME, w których nie jest wystarczająco inteligentny, aby to zrobić. –

+0

Teraz jest jasne. Widziałem kod bajtowy klasy i zaskoczyło mnie to, że bajt kodu zawiera dodatkową metodę tylko wtedy, gdy próbujesz utworzyć instancję klasy (na przykład w głównej metodzie). –

9

Jeśli chodzi o inne klasy, nie powinno tak być, ponieważ klasa wewnętrzna jest zadeklarowana jako prywatna. W ogóle go nie widzą.

Nie powinno to wpływać na otaczającą klasę, ponieważ zawiera wewnętrzną klasę.

+2

Wystarczy pamiętać, jeśli konstruktor klasy jest oznaczona jako 'private', niektóre narzędzia do kodowania standardową weryfikację takiego [Checkstyle] (http://checkstyle.sourceforge.net/) może sugerować, aby oznaczyć klasę jako' final' także. –

Powiązane problemy