Pregunta

Esta pregunta es una continuación de: ¿Por qué puede & # 8217; t Llamo a un método fuera de una clase anónima del mismo nombre

Esta pregunta anterior responde por qué , pero ahora quiero saber si javac debería encontrar una ejecución (barra de int). (Consulte la pregunta anterior para ver por qué falla la ejecución (42))

Si no debería, ¿se debe a una especificación? ¿Produce código ambiguo? Mi punto es, creo que esto es un error. Si bien la pregunta anterior explicó por qué este código no se compila, creo que debería compilar si javac buscó en el árbol si no encuentra una coincidencia en el nivel actual. ES DECIR. Si this.run () no coincide, debería verificar automáticamente NotApplicable.this para un método de ejecución.

También tenga en cuenta que foo (barra int) se encuentra correctamente. Si da alguna razón por la que no debe encontrarse run (int bar), también debe explicar por qué se encuentra foo (int bar).

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

Solución

Este comportamiento de javac se ajusta a la especificación. Consulte & # 167; 15.12 Método Expresiones de invocación en la Especificación del lenguaje Java, específicamente el párrafo debajo de " Compile Time Step 1 " explicando el significado de una invocación de método no calificado:

  

Si el identificador aparece dentro del alcance (& # 167; 6.3) de una declaración de método visible con ese nombre, entonces debe haber una declaración de tipo adjunto de la que ese método sea miembro. Sea T la declaración más interna de este tipo. La clase o interfaz a buscar es T.

En otras palabras, el método no calificado nombre se busca en todos los ámbitos delimitados, y la declaración de tipo " más interna " (lo que significa que una clase o una declaración de interfaz) en la que se encuentra el nombre es la que se buscará para toda la firma (en " Compile Time Step 2 ").

Otros consejos

Me suena como una receta de ambigüedad y fragilidad, tan pronto como se agrega un nuevo método a su clase base (bueno, no es tan probable para una interfaz ...) el significado de su código cambia por completo.

Las clases anónimas ya son bastante feas, ya que hacer este fragmento de forma explícita no me molesta en absoluto.

Probar

NotApplicable.this.run(42);

en su lugar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top