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.
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? –
@ Ł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ć. –
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). –