Hier erstelle ich eine Instanz meiner Klasse
Nein, Sie erstellen hier nicht die Instanz Ihrer abstrakten Klasse. Vielmehr erzeugen Sie eine Instanz einer anonyme Unterklasse Ihrer abstrakten Klasse. Und dann rufen Sie die Methode in Ihrer abstrakte Klasse Verweis auf Unterklassenobjekt .
Dieses Verhalten ist eindeutig aufgeführt in JLS - Abschnitt Nr. 15.9.1 : -
Wenn der Ausdruck zur Erzeugung der Klasseninstanz mit einer Klasse bo ist die zu instanzierende Klasse eine anonyme Klasse. Dann:
- Wenn T eine Klasse bezeichnet, dann wird eine anonyme direkte Unterklasse der durch T bezeichneten Klasse deklariert. Es ist ein Kompilierzeitfehler, wenn die Klasse, die durch T bezeichnet wird, eine finale Klasse ist.
- Wenn T eine Schnittstelle bezeichnet, dann wird eine anonyme direkte Unterklasse von Object deklariert, die die durch T bezeichnete Schnittstelle implementiert.
- In beiden Fällen ist der Body der Unterklasse der ClassBody, der im Ausdruck zur Erzeugung der Klasseninstanz angegeben ist.
- Die Klasse, die instanziiert wird, ist die anonyme Unterklasse.
Hervorhebung von mir.
Auch in JLS - Abschnitt # 12.5 können Sie sich über die Prozess der Objekterstellung . Ich möchte hier eine Aussage daraus zitieren: -
Jedes Mal, wenn eine neue Klasseninstanz erstellt wird, wird Speicherplatz zugewiesen Speicherplatz zugewiesen, der Platz für alle in der Klasse deklarierten Instanzvariablen deklarierten Instanzvariablen und alle Instanzvariablen, die in jeder Oberklasse der deklariert sind, einschließlich aller Instanzvariablen, die versteckt sein können.
Kurz bevor ein Verweis auf das neu erstellte Objekt zurückgegeben wird Ergebnis zurückgegeben wird, wird der angegebene Konstruktor verarbeitet, um das neue Objekts nach dem folgenden Verfahren zu initialisieren:
Das vollständige Verfahren können Sie unter dem von mir angegebenen Link nachlesen.
Um praktisch zu sehen, dass die Klasse, die instanziiert wird, eine Anonyme Unterklasse müssen Sie nur Ihre beiden Klassen kompilieren. Nehmen wir an, Sie haben diese Klassen in zwei verschiedenen Dateien abgelegt:
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();
}
}
Kompilieren Sie nun Ihre beiden Quelldateien:
javac My.java Poly.java
In dem Verzeichnis, in dem Sie den Quellcode kompiliert haben, finden Sie nun die folgenden Klassendateien:
My.class
Poly$1.class // Class file corresponding to anonymous subclass
Poly.class
Sehen Sie diese Klasse - Poly$1.class
. Es ist die vom Compiler erstellte Klassendatei, die der anonymen Unterklasse entspricht, die Sie mit dem unten stehenden Code instanziiert haben:
new My() {};
Es ist also klar, dass eine andere Klasse instanziiert wird. Es ist nur so, dass dieser Klasse erst nach der Kompilierung durch den Compiler ein Name gegeben wird.
Im Allgemeinen werden alle anonymen Unterklassen in Ihrer Klasse auf diese Weise benannt:
Poly$1.class, Poly$2.class, Poly$3.class, ... so on
Diese Nummern geben die Reihenfolge an, in der diese anonymen Klassen in der umgebenden Klasse erscheinen.