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) {
    }
}
È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top