12
votes

Spécification de la langue Java - Impossible de comprendre «Blockstatement»

J'ai examiné la spécification de langue java ici ( Au lieu de cela, je devrais être une bière) et je suis curieux de savoir à quoi une méthode peut contenir. Les états des spécifications Un organisme de méthode peut contenir un bloc xxx pré>

où un "bloc" contient "Blockstatifs". La règle "Blockstatement" ressemble à ceci: p>

public class Foo {
    public void doFoo() {
        interface dooJa {
            int bar();
        }
    }
}


0 commentaires

5 Réponses :


6
votes

Oh oui, vous pouvez déclarer une classe à l'intérieur d'un corps de méthode. : -)

class A {

    public void doIt() {
        class B {}
        B b = new B();
        System.out.println(b.getClass());
    }

}


5 commentaires

Eh bien, je serai ... je pensais une sorte de classe intérieure anonyme ou quelque chose du genre. Merci pour ça.


Au fait, je pensais être proactif en essayant cela à Eclipse. Cependant, cela m'a donné une erreur lorsque j'ai utilisé l'identifiant «public», qui n'est pas autorisé (seulement abstrait ou final), mais j'ai eu l'erreur et je viens de supposer (sans vérifier) ​​que vous ne pouviez pas définir une classe ou une interface dans un méthode.


Définir une interface dans une méthode ne fonctionnera cependant pas pour moi. Dans Eclipse, je reçois une erreur indiquant: "L'interface membre DOOJA ne peut être définie que dans une classe ou une interface de niveau supérieur". Définir une classe fonctionne cependant.


Eh bien, vous pouvez toujours utiliser une classe interne anonyme pour créer une instance de l'interface dans la méthode enfermante, non?


Mais vous ne pourrez pas le retourner (à moins que vous ne prévoyez de retourner un objet) puisque le monde extérieur ne sait pas sur l'interface. En outre, quel est le point dans l'application d'un contrat qui est la méthode cadrod? :)



1
votes

Exemple d'un bloc avec une déclaration de classe interne:

public class Test {

    static 
    {
        class C {}
        C c = new C();
    }
}


0 commentaires

1
votes

Comme d'autres l'ont dit, vous peut em> déclarer une classe à l'intérieur d'une méthode. Un cas d'utilisation consiste à utiliser cela comme alternative pour une classe intérieure anonyme. Les classes intérieures anonymes ont des inconvénients; Par exemple, vous ne pouvez pas déclarer un constructeur dans une classe intérieure anonyme. Avec une classe déclarée localement dans une méthode, vous pouvez.

Voici un exemple idiot qui ne montre pas vraiment pourquoi vous voudriez faire cela, mais au moins comment vous pourriez le faire. P>

public Runnable createTask(int a, int b) {
    // Method-local class with a constructor
    class Task implements Runnable {
        private int x, y;

        Task(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public void run() {
            System.out.println(x + y);
        }
    }

    return new Task(a, b);
}


1 commentaires

Certes que, mais la même chose ne semble pas s'appliquer à une interface, même pensait que la spécification de langue indique que vous pouvez définir une interface également.



4
votes

Vous avez fait une bonne observation sur les interfaces qui ne fonctionnent plus. La raison est que vous regardez une très ancienne version de la grammaire. Il semble avoir plus de 10 ans. Jetez un coup d'œil à la grammaire pour Java 6 (ce que vous testez probablement):

http://www.it. bton.ac.uk/staff/rnb/bosware/javasyntax/ruolesLinked.html#BlockStatement

Vous verrez Blockstatement:

Blockstatement: LocalvariabledeclarationStatement Classdeclaration Déclaration


2 commentaires

C'est beaucoup mieux! Merci pour ça. Maintenant, où est cette bière :-)


Aucun problème. Pour être plus précis, c'est la page qui décrit les différents ajouts de la spécification de langue: java.sun.com/docs/books/jls/index.html



1
votes

Celles-ci sont appelées classes locales. Je l'utilise de temps en temps, mais ce n'est pas vraiment une nécessité.

Edit: une classe locale peut être statique, s'il apparaît dans un contexte statique, par exemple dans une méthode statique.

à partir du libellé de la spécification, classe locale / interne / anno signifie toujours class uniquement, pas interface .


0 commentaires