"Нормальний" внутрішній клас має прихований (неявний) вказівник на екземпляр Зовнішнього класу. Це дозволяє компілятору генерувати код, щоб переслідувати вказівник за вами, не потребуючи введення його. Наприклад, якщо в зовнішньому класі є змінна "a", то код у вашому внутрішньому класі може просто робити "a = 0", але компілятор генерує код для "externalPointer.a = 0", підтримуючи прихований покажчик під обкладинки.
Це означає, що коли ви створюєте екземпляр внутрішнього класу, ви повинні мати екземпляр зовнішнього класу, щоб пов’язати його. Якщо ви робите це створення всередині методу зовнішнього класу, тоді компілятор знає використовувати "це" як неявний покажчик. Якщо ви хочете встановити посилання на якийсь інший зовнішній екземпляр, тоді ви використовуєте спеціальний "новий" синтаксис (див. Фрагмент коду нижче).
Якщо ви зробите свій внутрішній клас "статичним", то прихованого вказівника немає, і ваш внутрішній клас не може посилатися на членів зовнішнього класу. Статичний внутрішній клас ідентичний звичайному класу, але його ім'я визначається всередині батьківського.
Ось фрагмент коду, який демонструє синтаксис для створення статичних та нестатичних внутрішніх класів:
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
}
}