Qui, sto creando l'istanza della mia classe
No, non stai creando l'istanza della tua classe astratta qui. Piuttosto stai creando un'istanza di una sottoclasse anonima della tua classe astratta. E quindi stai invocando il metodo sul riferimento di classe astratto che punta all'oggetto della sottoclasse .
Questo comportamento è chiaramente elencato in JLS - Sezione # 15.9.1 : -
Se l'espressione di creazione dell'istanza di classe termina in un corpo di classe, la classe da istanziare è una classe anonima. Poi:
- Se T indica una classe, viene dichiarata una sottoclasse diretta anonima della classe denominata da T. È un errore in fase di compilazione se la classe indicata da T è una classe finale.
- Se T indica un'interfaccia, viene dichiarata una sottoclasse diretta anonima di Object che implementa l'interfaccia denominata da T.
- In entrambi i casi, il corpo della sottoclasse è il ClassBody fornito nell'espressione di creazione dell'istanza di classe.
- La classe che viene istanziata è la sottoclasse anonima.
Enfasi mia.
Inoltre, in JLS - Sezione # 12.5 , puoi leggere il processo di creazione degli oggetti . Citerò una dichiarazione da quella qui: -
Ogni volta che viene creata una nuova istanza di classe, lo spazio di memoria viene allocato per essa con spazio per tutte le variabili di istanza dichiarate nel tipo di classe e tutte le variabili di istanza dichiarate in ciascuna superclasse del tipo di classe, comprese tutte le variabili di istanza che possono essere nascoste.
Appena prima che venga restituito un riferimento all'oggetto appena creato, il costruttore indicato viene elaborato per inizializzare il nuovo oggetto usando la seguente procedura:
Puoi leggere la procedura completa sul link che ho fornito.
Per vedere praticamente che la classe che viene istanziata è una sottoclasse anonima , devi solo compilare entrambe le classi. Supponiamo di mettere quelle classi in due file diversi:
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();
}
}
Ora compila entrambi i tuoi file sorgente:
javac My.java Poly.java
Ora nella directory in cui hai compilato il codice sorgente, vedrai i seguenti file di classe:
My.class
Poly$1.class // Class file corresponding to anonymous subclass
Poly.class
Vedi quella classe - Poly$1.class
. È il file di classe creato dal compilatore corrispondente alla sottoclasse anonima creata da un'istanza utilizzando il codice seguente:
new My() {};
Quindi, è chiaro che è stata istanziata una classe diversa. È solo che, a quella classe viene assegnato un nome solo dopo la compilazione da parte del compilatore.
In generale, tutte le sottoclassi anonime della tua classe saranno nominate in questo modo:
Poly$1.class, Poly$2.class, Poly$3.class, ... so on
Quei numeri indicano l'ordine in cui quelle classi anonime compaiono nella classe allegata.
B
da un unico astrattaA
, durante la parte di costruzione diB
esempio, che consistono in esecuzioneA
's costruttore, tipo di runtime dell'oggetto è in realtàA
. Solo temporaneo tuttavia.