In questo momento sto implementando un metodo che ha un parametro del tipo Classe e questo metodo restituisce un valore booleano se l'oggetto della classe data richiede un'istanza della classe che lo include per essere istanziato.Java: come determinare se una classe locale definita in un blocco di inizializzazione richiede un'istanza di inclusione per l'istanziazione?
Questo metodo attualmente funziona nel modo seguente:
if (clazz.getEnclosingClass() == null) {
return false;
}
if (clazz.isAnonymousClass() || clazz.isMemberClass()) {
return !Modifier.isStatic(clazz.getModifiers());
}
if (clazz.getEnclosingConstructor() != null) {
return true;
}
final Method enclosingMethod = clazz.getEnclosingMethod();
if (enclosingMethod != null) {
return !Modifier.isStatic(enclosingMethod.getModifiers());
}
Per spiegare il motivo per cui è stato progettato come tale:
- Prima si verifica se si tratta di una classe di primo livello, in caso affermativo, l'algoritmo può sicuro restituire false
- Se la classe è anonima o una classe membro, richiede un'istanza di chiusura se non è statica (una classe anynmous è statica automaticamente se è dichiarata in un costruttore statico/metodo/blocco inizializzatore)
- La classe può ora essere assunta come una classe locale (ignorando array e primitive), quindi è definita in un costruttore, un metodo o un inizializzatore. Tuttavia, a differenza di una classe anonima, una classe locale non viene mai considerata statica, ma richiede comunque un'istanza di inclusione se la classe locale è definita in un blocco non statico.
- Un costruttore non è mai statica, quindi in questo caso tornare vero
- Se è definita in un metodo, restituirà true se il metodo non è statico
ho bisogno passaggio 6 per determinare se la classe locale risiede in un blocco di inizializzazione statico o in un blocco di inizializzazione di istanze, quindi ho finito con l'implementazione per questa funzione.
Quindi ecco dove l'API di riflessione è un po 'corta. Non esiste alcun metodo Class.getEnclosingInitializer()
o simile, né esiste una classe che rappresenta un inizializzatore nel pacchetto di riflessione.
Non è un blocco di inizializzazione un membro di una classe? Nella specifica java 1.8 l'interfaccia Membro ha solo le classi di implementazione Campo, Eseguibile (con sottoclassi Costruttore e Metodo), e poi c'è MemberName che è fuori dal campo di applicazione per la maggior parte degli utenti di riflessione.
Non sono sicuro che le persone dietro le specifiche abbiano dimenticato questa situazione e le classi locali dovrebbero essere statiche se dichiarate in un metodo statico/inizializzatore (come le classi anonime). Ma mi sembra che manchi questa ultima dose di coerenza da questo punto di vista.
Così qualcuno ha un'idea su come accertare in quale tipo di blocco di inizializzazione viene dichiarata la classe locale?
io non sono davvero appassionato di scavare attraverso i campi per una sintetica uno di un tipo che è uguale è che racchiude classe, o loop attraverso la sua costruttori di qualcosa di simile a quello (nota a margine: oggetti Parameter da Constructor.getParameters()
restituiscono sempre false su isImplicit()
e isSynthetic()
non importa quello che provo ... sembra solo sbagliato). Quindi se posso evitare tali soluzioni sarebbe fantastico.
sembra più una discussione che una domanda. –
Beh, ho bisogno di un modo per determinare X, e usare il metodo Y è qualcosa che desidero evitare, quindi la mia domanda è "qual è il metodo Z per determinare X di cui non sono a conoscenza?". – grimmeld