„Zwykła” klasa wewnętrzna ma ukryty (niejawny) wskaźnik do instancji klasy Outer. Pozwala to kompilatorowi na wygenerowanie kodu do śledzenia wskaźnika bez konieczności wpisywania go. Na przykład, jeśli w klasie zewnętrznej znajduje się zmienna „a”, wówczas kod w klasie wewnętrznej może po prostu wykonać „a = 0”, ale kompilator wygeneruje kod dla „externalPointer.a = 0”, utrzymując ukryty wskaźnik pod osłony.
Oznacza to, że kiedy tworzysz instancję klasy wewnętrznej, musisz mieć instancję klasy zewnętrznej, z którą możesz ją połączyć. Jeśli zrobisz to wewnątrz metody klasy zewnętrznej, wówczas kompilator będzie wiedział, że używa "this" jako niejawnego wskaźnika. Jeśli chcesz utworzyć link do innej zewnętrznej instancji, użyj specjalnej „nowej” składni (zobacz fragment kodu poniżej).
Jeśli sprawisz, że Twoja klasa wewnętrzna stanie się „statyczna”, wtedy nie będzie ukrytego wskaźnika, a Twoja klasa wewnętrzna nie będzie mogła odwoływać się do członków klasy zewnętrznej. Statyczna klasa wewnętrzna jest identyczna z klasą zwykłą, ale jej nazwa jest objęta zakresem wewnątrz elementu nadrzędnego.
Oto fragment kodu, który demonstruje składnię tworzenia statycznych i niestatycznych klas wewnętrznych:
public class MyClass {
int a,b,c; // Some members for MyClass
static class InnerOne {
int s,e,p;
void clearA() {
//a = 0; Can't do this ... no outer pointer
}
}
class InnerTwo {
//MyClass parentPointer; Hidden pointer to outer instance
void clearA() {
a = 0;
//outerPointer.a = 0 The compiler generates this code
}
}
void myClassMember() {
// The compiler knows that "this" is the outer reference to give
// to the new "two" instance.
InnerTwo two = new InnerTwo(); //same as this.new InnerTwo()
}
public static void main(String args[]) {
MyClass outer = new MyClass();
InnerTwo x = outer.new InnerTwo(); // Have to set the hidden pointer
InnerOne y = new InnerOne(); // a "static" inner has no hidden pointer
InnerOne z = new MyClass.InnerOne(); // In other classes you have to spell out the scope
}
}