«Обычный» внутренний класс имеет скрытый (неявный) указатель на экземпляр внешнего класса. Это позволяет компилятору сгенерировать код для отслеживания указателя без необходимости его ввода. Например, если есть переменная «a» во внешнем классе, тогда код во внутреннем классе может просто выполнять «a = 0», но компилятор сгенерирует код для «outerPointer.a = 0», сохраняя скрытый указатель под обложки.
Это означает, что когда вы создаете экземпляр внутреннего класса, у вас должен быть экземпляр внешнего класса, чтобы связать его. Если вы делаете это создание внутри метода внешнего класса, компилятор знает, что нужно использовать this в качестве неявного указателя. Если вы хотите установить ссылку на какой-либо другой внешний экземпляр, используйте специальный «новый» синтаксис (см. Фрагмент кода ниже).
Если вы сделаете свой внутренний класс «статическим», тогда не будет скрытого указателя, и ваш внутренний класс не сможет ссылаться на члены внешнего класса. Статический внутренний класс идентичен обычному классу, но его имя находится внутри родительского класса.
Вот фрагмент кода, демонстрирующий синтаксис для создания статических и нестатических внутренних классов:
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
}
}