Question

Cette question fait suite à: Pourquoi can & # 8217; Je n'appelle pas une méthode en dehors d'une classe anonyme du même nom

Cette question précédente répond à pourquoi , mais maintenant je veux savoir si javac devrait trouver run (int bar)? (Voir la question précédente pour voir pourquoi run (42) échoue)

Si ce n’est pas le cas, est-ce dû à une spécification? Est-ce que cela produit un code ambigu? Mon point est, je pense que c'est un bug. Alors que la question précédente expliquait pourquoi ce code échouait à la compilation, j'estime qu'il devrait le faire si javac effectuait une recherche plus haut dans l'arborescence s'il ne parvenait pas à trouver une correspondance au niveau actuel. C'EST À DIRE. Si this.run () ne correspond pas, il devrait automatiquement vérifier NotApplicable.this pour une méthode d'exécution.

Notez également que foo (int bar) est correctement trouvé. Si vous donnez une raison quelconque pour laquelle run (int bar) ne devrait pas être trouvé, il doit également expliquer pourquoi foo (int bar) est trouvé.

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) {
    }
}
Était-ce utile?

La solution

Ce comportement de javac est conforme à la spécification. Voir & # 167; 15.12 Expressions d'invocation de méthode dans la spécification du langage Java, en particulier le paragraphe sous "Durée de la compilation, étape 1" " expliquant la signification d'une invocation de méthode non qualifiée:

  

Si l'identificateur apparaît dans la portée (& # 167; 6.3) d'une déclaration de méthode visible portant ce nom, il doit exister une déclaration de type englobante dont cette méthode est membre. Soit T la déclaration la plus profonde de ce type. La classe ou l'interface à rechercher est T.

En d'autres termes, la méthode non qualifiée nom est recherchée dans toutes les portées englobantes, ainsi que la "déclaration de type la plus interne" (ce qui signifie soit une déclaration de classe, soit une déclaration d’interface) dans laquelle le nom est trouvé est celui dans lequel sera recherchée la signature entière (dans "Compile Time Step 2").

Autres conseils

Cela me semble être une recette d'ambiguïté et de fragilité - dès qu'une nouvelle méthode est ajoutée à votre classe de base (d'accord, ce n'est probablement pas le cas pour une interface ...), la signification de votre code change complètement.

Les classes anonymes sont déjà très laides - ce type d’explication ne me gêne pas du tout.

Essayez

NotApplicable.this.run(42);

à la place.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top