Javac dovrebbe trovare metodi al di fuori di una classe anonima con lo stesso nome?
-
05-07-2019 - |
Domanda
Questa domanda è una risposta a: Perché è possibile chiamo un metodo al di fuori di una classe anonima con lo stesso nome
Questa domanda precedente risponde perché , ma ora voglio sapere se javac dovrebbe trovare run (int bar)? (Vedi la domanda precedente per capire perché run (42) fallisce)
In caso contrario, è dovuto a una specifica? Produce codice ambiguo? Il mio punto è, penso che questo sia un bug. Mentre la domanda precedente ha spiegato perché questo codice non riesce a essere compilato, penso che dovrebbe essere compilato se javac cercasse più in alto nella struttura se non riuscisse a trovare una corrispondenza al livello attuale. IE. Se this.run () non corrisponde, dovrebbe automaticamente controllare NotApplicable.this per un metodo di esecuzione.
Si noti inoltre che foo (int bar) è stato trovato correttamente. Se dai qualche motivo per cui run (int bar) non dovrebbe essere trovato, devi anche spiegare perché foo (int bar) viene trovato.
public class NotApplicable {
public NotApplicable() {
new Runnable() {
public void run() {
// this works just fine, it automatically used NotApplicable.this when it couldn't find this.foo
foo(42);
// this fails to compile, javac find this.run(), and it does not match
run(42);
// to force javac to find run(int bar) you must use the following
//NotApplicable.this.run(42);
}
};
}
private void run(int bar) {
}
public void foo(int bar) {
}
}
Soluzione
Questo comportamento di javac è conforme alle specifiche. Vedi & # 167; 15.12 Espressioni di invocazione del metodo nelle specifiche del linguaggio Java, in particolare il paragrafo sotto " Compile Time Step 1 " spiegazione del significato di un'invocazione di metodo non qualificata:
Se l'identificatore appare nell'ambito (& # 167; 6.3) di una dichiarazione di metodo visibile con quel nome, allora deve esserci una dichiarazione di tipo accludente di cui quel metodo è membro. Sia T la più intima dichiarazione di questo tipo. La classe o l'interfaccia da cercare è T.
In altre parole, il metodo non qualificato nome viene cercato in tutti gli ambiti racchiusi e la più intima "dichiarazione di tipo" " (che significa una dichiarazione di classe o un'interfaccia) in cui viene trovato il nome è quello che verrà cercato per l'intera firma (in "Compile Time Step 2").
Altri suggerimenti
Sembra una ricetta per ambiguità e fragilità per me - non appena viene aggiunto un nuovo metodo nella classe di base (ok, non è così probabile per un'interfaccia ...) il significato del tuo codice cambia completamente.
Le lezioni anonime sono già abbastanza brutte - rendere questo po 'esplicito non mi disturba affatto.
Prova
NotApplicable.this.run(42);
, invece.