2008-10-31 8 views
4

Cette question fait suite à: Why can’t I call a method outside of an anonymous class of the same nameEst-ce que javac devrait trouver des méthodes en dehors d'une classe anonyme du même nom?

Cette réponse précédente question pourquoi, mais maintenant je veux savoir si javac devrait trouver run (bar int)? (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? Produit-t-il un code ambigu? Mon point est, je pense que c'est un bug. Alors que la question précédente expliquait pourquoi ce code ne compilait pas, je pense qu'il devrait compiler si javac cherchait plus haut dans l'arbre s'il n'arrivait pas à trouver une correspondance au niveau actuel. C'EST À DIRE. Si this.run() ne correspond pas, il doit vérifier automatiquement NotApplicable.this pour une méthode d'exécution.

Notez également que foo (int bar) est correctement trouvé. Si vous donnez une raison pour laquelle run (int bar) ne devrait pas être trouvé, cela doit aussi 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) { 
    } 
} 

Répondre

4

Ce comportement de javac est conforme à la spécification. Voir §15.12 Method Invocation Expressions dans la spécification du langage Java, en particulier le paragraphe sous « Compile temps Étape 1 » expliquant la signification d'un appel de méthode non qualifiée:

Si l'identificateur apparaît dans le cadre (§ 6.3) d'une déclaration de méthode visible ce nom, il doit y avoir une déclaration de type englobante dont cette méthode est membre. Soit T la déclaration la plus interne de ce type. La classe ou une interface de recherche est T.

En d'autres termes, la méthode non qualifiée nom est recherché dans toutes les étendues enserrant, et la « déclaration de type » plus à l'intérieur (ce qui signifie soit une classe ou d'une déclaration d'interface) dans lequel le nom est trouvé est celui qui sera recherché pour toute la signature (dans "Compile Time Step 2").

+0

Merci, je pense que je comprends la spécification. Maintenant, je peux faire valoir que c'est une mauvaise spécification et devrait être changé. Compile Time L'étape 1 doit inclure la classe englobante de la classe anonyme. – Pyrolistical

1

sonne comme une recette pour moi l'ambiguïté et la fragilité - dès qu'une nouvelle méthode est ajoutée dans votre classe de base (ok, pas probable pour une interface ...) le sens de votre code change complètement .

Les classes anonymes sont déjà assez moche - ce qui rend ce peu explicite ne me dérange pas du tout.

+0

Ok, alors pourquoi javac est-il autorisé à trouver foo (int bar)? C'est la même recette. – Pyrolistical

+0

C'est vrai. Bah, tout est désastreux. Donnez-moi les fermetures appropriées :) –

1

Essayez

NotApplicable.this.run(42); 

à la place.

+0

Notez qu'au moment où j'ai écrit cette réponse, le commentaire avec ce même morceau de code n'était pas présent dans la question. – nsayer

Questions connexes