Eu não consigo entender oracle java tutorial que escreve:
public class SyntheticConstructor {
private SyntheticConstructor() {}
class Inner {
// Compiler will generate a synthetic constructor since
// SyntheticConstructor() is private.
Inner() { new SyntheticConstructor(); }
}
}
Desde referências construtor da classe interna do construtor privado da classe delimitador, o compilador deve gerar um construtor pacote-privadas da classe delimitador (que é SyntheticConstructor
aqui).
Então, por que o compilador Java tem que criar o construtor sintético na classe externa SyntheticConstructor
?
Isto é causado por uma discrepância entre as regras de acesso da linguagem Java e as regras de acesso do JVM.
Será que a JVM não tem o conceito de classes internas, que é inteiramente uma construção feita-up inventado pelo compilador Java. O código compilado do arquivo fonte é 2 classes independentes.
Quando o código fonte é a seguinte:
public class SyntheticConstructor {
private SyntheticConstructor() {}
class Inner {
Inner() { new SyntheticConstructor(); }
}
}
O compilador gera .class
arquivos equivalentes para o código de fonte seguinte (de javap
código byte desmontado):
public class SyntheticConstructor extends Object {
private SyntheticConstructor() {
super();
return;
}
}
class SyntheticConstructor$Inner extends Object {
final SyntheticConstructor this$0;
SyntheticConstructor$Inner(SyntheticConstructor outer) {
this.this$0 = outer;
super();
new SyntheticConstructor();
return;
}
}
Nesse código, a new SyntheticConstructor()
expressão está tentando invocar o private
construtor de outra classe. Desde que não é permitido pela JVM, o compilador deve criar um construtor não-privados sintética oculto que ele pode chamar em seu lugar.
Isto é verdade, sempre que o código em uma classe externa / interna / aninhada acede a um membro particular de outra classe exterior / interior / aninhada da mesma classe de nível superior.