113 votes

Est-il possible de rendre anonymes les classes internes en Java statique?

En Java, les classes internes peuvent être static ou pas. Si elles sont static, ils ne contiennent pas de référence à l'indicateur de l'contenant de l'instance (ils sont aussi appelés les classes internes plus, ils sont appelés classes imbriquées). Oublier de faire un intérieur de classe static quand il n'a pas besoin de cette référence peut conduire à des problèmes de collecte des ordures ou d'échapper à l'analyse.

Il est possible de faire un anonyme intérieur de la classe static ? Ou ne le compilateur comprendre cela automatiquement (ce qui pourrait, parce qu'il ne peut y avoir toutes les sous-classes)?

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

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

131voto

Michael Myers Points 82361

Non, vous ne pouvez pas, et non, le compilateur ne peut pas le comprendre. C'est pourquoi, FindBugs toujours suggère de modifier les classes internes anonymes à l' static classes imbriquées si ils n'utilisent pas leurs implicite this de référence.

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

Une classe anonyme est jamais abstract (§8.1.1.1). Une classe anonyme est toujours un à l'intérieur de la classe (§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).

Roedy Vert de Java Glossaire dit que le fait que les classes anonymes sont autorisés dans un contexte statique est dépendant de l'implémentation:

Si vous voulez déflecteur personnes chargées de la maintenance de votre code, wags ont découvert javac.exe permettra anonyme des classes à l'intérieur d' static code d'initialisation et d' static méthodes, même si le langage de spécification dit qu'anonyme classes ne sont jamais static. Ces classes anonymes, bien sûr, n'ont pas accès aux champs d'instance de l'objet. Je ne recommande pas de faire cela. La fonctionnalité peut être retiré à tout moment.

Edit 2: Le JLS couvre statique des contextes plus explicitement dans le §15.9.2:

Laissez - C être la classe instanciée, et laissez - je être l'instance créée. Si C est un intérieur de classe alors je peut avoir un immédiatement en joignant instance. Le immédiatement en joignant instance de i (§8.1.3) est déterminé comme suit.

  • Si C est une classe anonyme, puis:
    • Si la classe de création d'instance expression se produit dans un contexte statique (§8.1.3), alors je n'a pas immédiatement en joignant instance.
    • Sinon, les enfermant instance de je est - this.

Donc une classe anonyme dans un contexte statique est à peu près équivalent à un static classe imbriquée dans qu'il n'a pas de conserver une référence à la classe englobante, même si c'est techniquement pas un static classe.

14voto

Neil Coffey Points 13408

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

Quoi que vous les appelez, ces modèles (et quelques variantes avec différents visibilité) sont tous les possibles, normal, juridique 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 charge dans la langue spec (si vous êtes vraiment gêné, voir la section 15.9.5.1 pour l'un, à l'intérieur de la méthode statique).

Mais cette citation est tout simplement faux:

javac.exe permettra anonyme classes à l'intérieur de statique de code d'initialisation et les méthodes statiques, même si l' langage de spécification dit qu'anonyme les classes ne sont jamais statiques

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

Honnêtement, tous les modèles ci-dessus sont très bien (ce que vous appelez "imbriqués", "intérieur", "anonyme" quoi que...). Vraiment, personne ne va soudainement supprimer cette fonctionnalité dans la prochaine version de Java. Honnêtement!

14voto

Genre de. Un anonyme intérieure classe créée dans une méthode statique sera évidemment efficacement statique, car il n'y a pas de source extérieure.

Il y a quelques différences techniques entre les classes internes statique dans des contextes et statique classes imbriquées. Si vous êtes intéressé, lisez les JLS 3ème Ed.

6voto

Andrew Duffy Points 3574

Les classes internes ne peuvent pas être statique statique classe imbriquée n'est pas un intérieur de classe. La Java tutoriel en parle ici.

-3voto

Terra Caines Points 962

Sur la note de rendre anonyme intérieur de la classe statique en les appelant à l'intérieur d'une méthode statique.

Ce n'est pas réellement supprimer la référence. Vous pouvez tester cela en essayant de sérialiser la classe anonyme et de ne pas faire de la classe englobante serializable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: