Qualcuno può indicarmi la parte della specifica che risolve questo problema?
Questo sarà principalmente essere definito nella sezione relativa Method invocation expressions:
Il primo passo nella elaborazione di una chiamata di metodo in fase di compilazione è figura il nome del metodo da richiamare e quale classe oppure interfaccia per cercare le definizioni dei metodi di quel nome.
Per la classe o l'interfaccia per la ricerca, ci sono sei casi da considerare, a seconda della forma che precede la parentesi sinistra del MethodInvocation:
- [...]
- Se il modulo è
Primary . [TypeArguments] Identifier
, quindi lasciare T
essere il tipo di espressione primaria. La classe o l'interfaccia per cercare è T
se T
è una classe o un tipo di interfaccia o il limite superiore di T
se T
è una variabile di tipo.
Qui, l'espressione primaria è il class instance creation expression. Quindi il tipo da cercare è il tipo anonimo.
Ho ragione nel pensare che l'unico modo per invocare ciao è immediatamente simile a questo. Che dire della riflessione?
Finché espressione restituisce il tipo anonimo T
, sia attraverso l'accesso diretto come voi avere, o tramite farmaci generici, si ha accesso (a regole di accesso regolari) ai membri che T
dichiara. Questo non è limitato ai metodi. Puoi accedere a campi o tipi, anche se non è così utile per i tipi. Ad esempio,
Object var = new Object() {
class Nested {
}
}.new Nested();
Dal momento che non c'è modo di fare riferimento al tipo nidificato senza il tipo di inclusione, non è possibile dichiarare una variabile di quel tipo nidificato. L'utilità diminuisce molto rapidamente. (Presumibilmente, questo è anche il motivo per cui non è possibile avere un tipo annidato static
all'interno di questa classe anonima.)
Reflection espone anche questo metodo. La classe anonima generata contiene questo metodo, quindi è possibile recuperarlo e richiamarlo. Il processo è lo stesso. Il fatto che l'istanza provenga da una classe anonima non ha importanza. Si applica la stessa strategia presentata in How do I invoke a Java method when given the method name as a string?.
Per esempio,
Object ref = new Object() {
public void method() {
System.out.println("hidden");
}
};
Class<?> anonymousClass = ref.getClass();
Method method = anonymousClass.getMethod("method");
method.invoke(ref, new Object[0]);
Non bisogna mai scrivere codice come questo.
[JLS-15.9.5. Dichiarazioni di classe anonime] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5) –
Dovresti riuscire ad arrivarci tramite la riflessione. Ma sì, questo è quasi completamente inutile.Se si desidera chiamare metodi, di solito si implementa un'interfaccia nella classe anonima. – Thilo
Bene, se si crea una classe anonima di un tipo più specifico (come un'implementazione anonima di * un'interfaccia *), è possibile conservare il riferimento in una variabile che consente di chiamare tali metodi a piacimento. –