Тут я створюю екземпляр свого класу
Ні, ви не створюєте тут екземпляр свого абстрактного класу. Швидше ви створюєте екземпляр анонімного підкласу вашого абстрактного класу. А потім ви посилаєтесь на метод у вашому абстрактному довіднику класу, що вказує на об’єкт підкласу .
Така поведінка чітко вказана в JLS - Розділ № 15.9.1 : -
Якщо вираз створення екземпляра класу закінчується в тілі класу, то інстанціюваний клас - це анонімний клас. Тоді:
- Якщо T позначає клас, то оголошується анонімний прямий підклас класу, названого T. Це помилка часу компіляції, якщо клас, позначений T, є кінцевим класом.
- Якщо T позначає інтерфейс, то оголошується анонімний прямий підклас Object, який реалізує інтерфейс, названий T.
- У будь-якому випадку тілом підкласу є ClassBody, що задається у виразі створення екземпляра класу.
- Клас, який інстанціюється, є анонімним підкласом.
Наголос мій.
Також у розділі №12.5 JLS ви можете прочитати про процес створення об’єктів . Я цитую тут одне твердження: -
Щоразу, коли створюється новий екземпляр класу, для нього виділяється простір пам’яті з простором для всіх змінних екземплярів, оголошених у класі класу, та всіх змінних екземплярів, оголошених у кожному надкласі типу класу, включаючи всі змінні екземпляра, які можуть бути приховані.
Незадовго до повернення в результаті посилання на щойно створений об'єкт, зазначений конструктор обробляється для ініціалізації нового об'єкта за допомогою наступної процедури:
Про повну процедуру ви можете прочитати за посиланням, яке я надав.
Щоб практично побачити, що клас, який інстанціюється, є Анонімним підкласом , вам просто потрібно скласти обидва класи. Припустимо, ви кладете ці класи у два різні файли:
My.java:
abstract class My {
public void myMethod() {
System.out.print("Abstract");
}
}
Poly.java:
class Poly extends My {
public static void main(String a[]) {
My m = new My() {};
m.myMethod();
}
}
Тепер, компілюйте обидва вихідні файли:
javac My.java Poly.java
Тепер у каталозі, де ви склали вихідний код, ви побачите такі файли класів:
My.class
Poly$1.class // Class file corresponding to anonymous subclass
Poly.class
Дивіться, що клас - Poly$1.class
. Це файл класу, створений компілятором, відповідний анонімному підкласу, який ви створили за допомогою наведеного нижче коду:
new My() {};
Отже, зрозуміло, що існує інший клас, який інстанціюється. Просто це класу присвоюється ім'я лише після складання компілятором.
Загалом усі анонімні підкласи у вашому класі будуть названі таким чином:
Poly$1.class, Poly$2.class, Poly$3.class, ... so on
Ці числа позначають порядок, в якому ці анонімні класи з’являються вкладному класі.
B
від абстрактногоA
, в протягом частини будівництва вB
разі, полягає працюєA
конструктор «s, тип виконання об'єкта насправдіA
. Однак лише тимчасові.