Est-il possible de créer des classes internes anonymes en Java?

En Java, les classes nestedes peuvent être static ou non. S’ils sont static , ils ne contiennent pas de référence au pointeur de l’instance contenant (ils ne sont plus appelés classes internes, ils sont appelés classes nestedes).

Oublier de rendre static une classe nestede lorsqu’elle n’a pas besoin de cette référence peut entraîner des problèmes lors de la récupération de la mémoire ou de l’parsing d’évasion.

Est-il possible de rendre static classe interne anonyme? Ou le compilateur le calcule-t-il automatiquement (ce qui est possible, car il ne peut y avoir de sous-classes)?

Par exemple, si je fais un comparateur anonyme, je n’ai presque jamais besoin de la référence à l’extérieur:

  Collections.sort(list, new Comparator(){ int compare(Ssortingng a, Ssortingng b){ return a.toUpperCase().compareTo(b.toUpperCase()); } } 

Non, vous ne pouvez pas, et non, le compilateur ne peut pas le comprendre. C’est pourquoi FindBugs suggère toujours de changer les classes internes anonymes en classes nestedes static nommées si elles n’utilisent pas this référence implicite.

Edit: Tom Hawtin – tackline dit que si la classe anonyme est créée dans un contexte statique (par exemple dans la méthode main ), la classe anonyme est en fait static . Mais le JLS n’est pas d’accord :

Une classe anonyme n’est jamais abstract (§8.1.1.1). Une classe anonyme est toujours une classe interne (§8.1.3); il n’est jamais static (§8.1.1, §8.5.1). Une classe anonyme est toujours implicitement final (§ 8.1.1.2).

Le Glossaire Java de Roedy Green dit que le fait que les classes anonymes soient autorisées dans un contexte statique dépend de l’implémentation:

Si vous souhaitez ignorer ceux qui maintiennent votre code, les wags ont découvert que javac.exe autorisait les classes anonymes à static intérieur du code d’initialisation static et static méthodes static , même si la spécification du langage indique que les classes anonymes ne sont jamais static . Ces classes anonymes, bien sûr, n’ont pas access aux champs d’instance de l’object. Je ne recommande pas de le faire. La fonctionnalité peut être extraite à tout moment.

Edit 2: Le JLS couvre en réalité plus explicitement les contextes statiques au § 15.9.2 :

Soit C la classe en cours d’instanciation et que je sois l’instance en cours de création. Si C est une classe interne, alors je peux avoir une instance immédiatement englobante. L’instance qui entoure immédiatement i (§8.1.3) est déterminée comme suit.

  • Si C est une classe anonyme, alors:
    • Si l’expression de création d’instance de classe se produit dans un contexte statique (§8.1.3), alors je n’ai pas d’instance englobante immédiate.
    • Sinon, l’instance qui entoure immédiatement i est la this .

Ainsi, une classe anonyme dans un contexte statique est à peu près équivalente à une classe nestede static dans la mesure où elle ne garde pas de référence à la classe englobante, même si techniquement, elle n’est pas une classe static .

Je pense qu’il y a un peu de confusion dans la nomenclature ici, ce qui est certes trop idiot et déroutant.

Quoi que vous les appeliez, ces modèles (et quelques variantes avec une visibilité différente) sont tous possibles, normaux, Java:

 public class MyClass { class MyClassInside { } } public class MyClass { public static class MyClassInside { } } public class MyClass { public void method() { JComponent jc = new JComponent() { ... } } } public class MyClass { public static void myStaticMethod() { JComponent jc = new JComponent() { ... } } } 

Ils sont pris en compte dans la spécification du langage (si vous êtes vraiment dérangé, consultez la section 15.9.5.1 pour celle de la méthode statique).

Mais cette citation est tout simplement fausse :

javac.exe autorisera les classes anonymes à l’intérieur du code init statique et des méthodes statiques, même si la spécification du langage indique que les classes anonymes ne sont jamais statiques

Je pense que l’auteur cité confond le mot-clé statique avec le contexte statique. (Certes, le JLS est aussi un peu déroutant à cet égard.)

Honnêtement, tous les schémas ci-dessus sont bons (quoi que vous les appeliez “nesteds”, “intérieurs”, “anonymes”, etc.). En réalité, personne ne va supprimer soudainement cette fonctionnalité dans la prochaine version de Java. Honnêtement!

Genre de. Une classe interne anonyme créée dans une méthode statique sera évidemment statique car il n’y a pas de source pour cela.

Il existe des différences techniques entre les classes internes dans les contextes statiques et les classes nestedes statiques. Si cela vous intéresse, lisez le 3ème éd.

Les classes internes ne peuvent pas être statiques – une classe nestede statique n’est pas une classe interne. Le tutoriel Java en parle ici .

les classes internes anonymes ne sont jamais statiques (elles ne peuvent pas déclarer de méthodes statiques ou de champs statiques non finaux), mais si elles sont définies dans un contexte statique (méthode statique ou champ statique), elles se comportent de manière statique accéder aux membres non statiques (ie instance) de la classe englobante (comme tout le rest à partir d’un contexte statique)

Sur la note de rendre une classe interne anonyme statique en les appelant dans une méthode statique.

Cela ne supprime pas réellement la référence. Vous pouvez tester cela en essayant de sérialiser la classe anonyme et de ne pas rendre sérialisable la classe englobante.