Questo generalmente non si applica a Java. I controlli di accesso vengono eseguiti una sola volta durante il processo Resolution. Quando il metodo Java è compilato con JIT, i riferimenti simbolici sono già risolti e verificati. Di fatto, l'inlining non viene eseguito sul bytecode originale, ma sulla rappresentazione intermedia specifica del compilatore. Quindi, i modificatori di accesso di solito non hanno effetti collaterali.
Tuttavia, posso scrivere un banco di prova artificiale di un modificatore private
/public
influisce notevolmente le prestazioni:
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
Questo effetto si spiega con un metodo di sintesi access$000
che javac
genera a consentire l'accesso a un membro privato della classe interna. Nel caso di test sopra descritto, questo accessorio aggiuntivo impedisce di inlining, poiché il livello massimo predefinito di inlining in HotSpot è 9 (-XX:MaxInlineLevel=9
). Poiché getPrivate()
non può essere richiamato direttamente dalla classe esterna, il metodo access$000()
aggiuntivo esegue il 10 ° livello di chiamata e pertanto non è in linea.