У мене є кілька питань, що стосуються вкладеного класу в Java.
Як вкладені класи з'являються "під капотом", щодо розподілу пам'яті?
Ви не можете оголосити статичну змінну в межахвкладеного класу (я думаю, точна помилка полягає в тому, що статичні атрибути можуть бути оголошені лише в класі верхнього рівня). Чому це та які інші обмеження існують для вкладених класів?
Якщо можливо, будь ласка, скажіть, чи є ваша відповідь Java-специфічною, чи C ++ також дотримується тих самих правил?
Відповіді:
1 для відповіді № 1Внутрішні класи точно такі ж, як і звичайнікласи щодо пам'яті та компіляції. (Можливо, є певна відмінність у способі, яким вони керовані в пам'яті, але це не видно середньому розробнику Java). Фактично, коли ви складаєте клас із внутрішнім класом, ви можете побачити складений файл .class як OuterClass$InnerClass.class
. Наскільки я знаю, JVM розглядає їх однаково.
Що стосується статичних змінних, то я не впевнений, що це питання. Наприклад, це працює для мене:
public class Tester {
public static void main(String[] args) {
System.out.println(InnerTester.MY_STRING);
}
public class InnerTester {
public static final String MY_STRING = "MY_STRING";
}
}
РЕДАГУВАТИ
Як зазначив Джеффрі, це не складається:
public class Tester {
public static void main(String[] args) {
System.out.println(InnerTester.MY_STRING);
}
public class InnerTester {
public static String MY_STRING = "MY_STRING";
}
}
Різниця полягає в тому, що я мав першу статичну змінну, яка перелічена як остаточна.
Подумавши про це деякий час, я згоден з @Eugene. Вони дозволяють бути статичними полями на внутрішніх класах final
тому що тоді немає проблем з ініціалізацією. Значення не можу змінити, ви просто ініціалізуєте його до свого значення. Якщо, однак, є статичне поле ні final
, то вам потрібно а екземпляр зовнішнього класу, який буде створено для ініціалізації поля, а статичні елементи не можуть бути прив'язані до окремих випадків.
я знайшов це обговорення на це також.
1 для відповіді № 2
В основному вкладене клас - це лише клас із полем, що посилається на екземпляр.
Якщо це не статичний вкладене клас (всередині якого ви можете оголосити статичні поля / методи). У цьому випадку це просто клас з іншим елементом шляху в назві (пакет + доданий клас імені).
Іншими словами. Нестатичний вкладене клас (внутрішній клас) - не може існувати без додавання екземпляра (наприклад, сторінки всередині книги). І ви вказуєте наступне:
Book book = ... // a book instance;
Book.Page page = book.new Page(); // requires an enclosing instance
Але статичний вкладене клас - абсолютно незалежний, це просто як питання про простір імен. Ви можете проаналізувати його як:
Outer.NestedStatic instance = new Outer.NestedStatic(); // just name-space
Більш детальна інформація тут: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
0 для відповіді № 3
Вкладений клас - це просто визначення типу всередині іншого класу. Java не хвилює, в якій мірі визначається новий тип, і вам не потрібно "обробляти" цей внутрішній клас будь-яким особливим способом.
Було б сенс мати нестатичний внутрішній клас із статичними полями, оскільки будь-яке посилання на нестатичний внутрішній клас обов'язково є змінною екземпляра. Тільки якщо виконано внутрішній клас static
чи можна було б статично призначити його - в цьому випадку статичний внутрішній клас є автономним класом, причому ім'я класу, що додає, діє як ще один рівень простору імен.