Zasadniczo nie dotyczy to środowiska Java. Kontrole dostępu są wykonywane tylko raz podczas procesu Resolution. Gdy metoda Java jest kompilowana JIT, referencje symboliczne są już rozwiązane i zweryfikowane. W rzeczywistości, wstawianie odbywa się nie na oryginalnym kodzie bajtowym, ale na specyficznej kompilacji reprezentacji pośredniej. Tak więc modyfikatory dostępu zwykle nie mają skutków ubocznych.
Jednakże, można napisać sztucznego sprawdzian gdzie private
/public
modyfikator znacząco wpływa na wydajność:
public class Test {
static final Inner inner = new Inner();
static class Inner {
int x = 1;
int getX1() { return x; }
int getX2() { return getX1(); }
int getX3() { return getX2(); }
int getX4() { return getX3(); }
int getX5() { return getX4(); }
int getX6() { return getX5(); }
int getX7() { return getX6(); }
int getX8() { return getX7(); }
int getX9() { return getX8(); }
private int getPrivate() { return getX9(); }
public int getPublic() { return getX9(); }
}
@GenerateMicroBenchmark
public int inlinePrivate() {
return inner.getPrivate();
}
@GenerateMicroBenchmark
public int inlinePublic() {
return inner.getPublic();
}
}
Benchmark Mode Thr Cnt Sec Mean Mean error Units
b.Test.inlinePrivate thrpt 1 3 5 289480,928 2247,656 ops/msec
b.Test.inlinePublic thrpt 1 3 5 1157970,245 18473,139 ops/msec
Zjawisko to tłumaczy się metody syntezy access$000
które javac
wytwarza się umożliwić dostęp do prywatnego członka klasy wewnętrznej. W powyższym teście ten dodatkowy akcesor zapobiega inlinowaniu, ponieważ domyślny maksymalny poziom wstawiania w HotSpot wynosi 9 (-XX:MaxInlineLevel=9
). Ponieważ getPrivate()
nie można wywołać bezpośrednio z klasy zewnętrznej, dodatkowa metoda access$000()
tworzy 10. poziom wywołania i dlatego nie jest inline.