Pergunta

Esta questão é um acompanhamento para: por que 't eu chamo de fora método de uma classe anônima de mesmo nome

Esta resposta da pergunta anterior por , mas agora eu quero saber se javac deve encontrar executado (int bar)? (Veja a pergunta anterior para ver por que correr (42) falhar)

Se ele não deveria, é devido a uma especificação? Será que produzir código ambígua? Meu ponto é, eu acho que este é um bug. Enquanto a questão anterior explicou por que este código não compilar, eu sinto que deve compilar se javac procurou superior na árvore se não conseguir encontrar uma correspondência no nível atual. IE. Se this.run () não corresponder, ele deve verificar automaticamente NotApplicable.this para um método de execução.

Observe também que foo (int bar) está correctamente encontrados. Se você dá alguma razão para que run (int bar) não deve ser encontrado, ele também deve explicar por que foo (int bar) é encontrado.

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) {
    }
}
Foi útil?

Solução

Este comportamento está em conformidade javac para o spec. Consulte §15.12 Method Invocation Expressões na Java Language Specification, especificamente o parágrafo em "tempo de compilação Passo 1", explicando o significado de uma invocação de método não qualificados:

Se o identificador aparece dentro do escopo (§6.3) de declaração um método visível com aquele nome, em seguida, tem de haver uma declaração do tipo envolvente de que o método é um membro. Seja T o mais íntimo tal declaração de tipo. A classe ou interface para pesquisa é T.

Em outras palavras, o método não qualificado nome é procurado em todos os âmbitos que encerram, eo mais íntimo "Tipo de declaração" (o que significa uma classe ou uma declaração de interface) em que o nome é encontrado é a que será procurado para toda a assinatura (em "tempo de compilação Passo 2").

Outras dicas

soa como uma receita para a ambigüidade e fragilidade para mim -., Logo que um novo método é adicionado em sua classe base (ok, não tão provável para uma interface ...) o significado de seu código muda completamente

aulas

anônimos são muito feio já - tornando este pouco de explícita não me incomoda em tudo.

Tente

NotApplicable.this.run(42);

em seu lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top