Utilisation de définitions de classe dans une méthode en Java


Exemple:

public class TestClass {

    public static void main(String[] args) {
        TestClass t = new TestClass();
    }

    private static void testMethod() {
        abstract class TestMethod {
            int a;
            int b;
            int c;

            abstract void implementMe();
        }

        class DummyClass extends TestMethod {
            void implementMe() {}
        }

        DummyClass dummy = new DummyClass();
    }
}

J'ai découvert que le morceau de code ci-dessus est parfaitement légal en Java. J'ai les questions suivantes.

  1. Quelle est l'utilité d'avoir une définition de classe dans une méthode?
  2. Un fichier de classe sera-t-il généré pour DummyClass
  3. Il m'est difficile d'imaginer ce concept de manière orientée objet. Avoir une définition de classe dans un comportement. Quelqu'un peut probablement me dire avec des exemples équivalents du monde réel.
  4. Classes abstraites à l'intérieur une méthode me semble un peu folle. Mais pas d'interfaces de permis. Est-il une raison derrière tout cela?
Author: Mahozad, 2010-03-11

6 answers

C'est ce qu'on appelle une classe locale.

2 est facile: oui, un fichier de classe sera généré.

1 et 3 sont un peu la même question. Vous utiliseriez une classe locale où vous n'avez jamais besoin d'instancier une ou de connaître les détails d'implémentation n'importe où, sauf dans une méthode.

Une utilisation typique serait de créer une implémentation jetable d'une interface. Par exemple, vous verrez souvent quelque chose comme ceci:

  //within some method
  taskExecutor.execute( new Runnable() {
       public void run() {
            classWithMethodToFire.doSomething( parameter );
       }
  }); 

Si vous aviez besoin d'en créer un tas et de le faire quelque chose avec eux, vous pourriez changer cela en

  //within some method
  class myFirstRunnableClass implements Runnable {
       public void run() {
            classWithMethodToFire.doSomething( parameter );
       }
  }
  class mySecondRunnableClass implements Runnable {
       public void run() {
            classWithMethodToFire.doSomethingElse( parameter );
       }
  }
  taskExecutor.execute(new myFirstRunnableClass());
  taskExecutor.execute(new mySecondRunnableClass());

En ce qui concerne les interfaces: je ne sais pas s'il y a un problème technique qui fait des interfaces définies localement un problème pour le compilateur, mais même s'il n'y en a pas, elles n'ajouteraient aucune valeur. Si une classe locale qui implémente une interface locale était utilisée en dehors de la méthode, l'interface n'aurait aucun sens. Et si une classe locale n'allait être utilisée qu'à l'intérieur de la méthode, l'interface et la classe seraient implémentées à l'intérieur de celle-ci méthode, de sorte que la définition de l'interface serait redondante.

 62
Author: Jacob Mattison, 2016-04-21 19:34:25

Ceux-ci sont appelés classes locales. Vous trouverez une explication détaillée et un exemple ici. L'exemple renvoie une implémentation spécifique que nous n'avons pas besoin de connaître en dehors de la méthode.

 14
Author: BalusC, 2010-03-11 20:02:32
  1. La classe ne peut pas être vue (c'est-à-dire instanciée, ses méthodes accessibles sans réflexion) de l'extérieur de la méthode. En outre, il peut accéder aux variables locales définies dans testMethod (), mais avant la définition de classe.

  2. Je pensais en fait: "Aucun fichier de ce type ne sera écrit."jusqu'à ce que je viens de l'essayer: Oh oui, un tel fichier est créé! Il s'appellera quelque chose comme un A 1B.class, où A est la classe externe, et B est la classe locale.

  3. Surtout pour le rappel fonctions (gestionnaires d'événements dans les interfaces graphiques, comme OnClick () lorsqu'un bouton est cliqué, etc.), il est assez habituel d'utiliser des "classes anonymes" - tout d'abord parce que vous pouvez vous retrouver avec beaucoup d'entre elles. Mais parfois, les classes anonymes ne sont pas assez bonnes - en particulier, vous ne pouvez pas définir un constructeur sur elles. Dans ces cas, ces classes locales de méthode peuvent être une bonne alternative.

 8
Author: Chris Lercher, 2010-03-11 20:00:56

Le véritable but de ceci est de nous permettre de créer des classes en ligne dans les appels de fonction pour consoler ceux d'entre nous qui aiment prétendre que nous écrivons dans un langage fonctionnel;)

 5
Author: Steve B., 2010-03-11 20:07:45

Le seul cas où vous souhaitez avoir une fonction complète classe interne vs classe anonyme ( alias fermeture Java ) est lorsque les conditions suivantes sont remplies

  1. vous devez fournir une interface ou une implémentation de classe abstraite
  2. vous souhaitez utiliser certains paramètres finaux définis dans la fonction d'appel
  3. vous devez enregistrer un état d'exécution de l'appel d'interface.

Par exemple, quelqu'un veut un Runnable et vous voulez enregistrer quand l'exécution a a commencé et s'est terminée.

Avec une classe anonyme, il n'est pas possible de le faire, avec une classe interne, vous pouvez le faire.

Voici un exemple qui démontre mon point

private static void testMethod (
        final Object param1,
        final Object param2
    )
{
    class RunnableWithStartAndEnd extends Runnable{
        Date start;
        Date end;

        public void run () {
            start = new Date( );
            try
            {
                evalParam1( param1 );
                evalParam2( param2 );
                ...
            }
            finally
            {
                end = new Date( );
            }
        }
    }

    final RunnableWithStartAndEnd runnable = new RunnableWithStartAndEnd( );

    final Thread thread = new Thread( runnable );
    thread.start( );
    thread.join( );

    System.out.println( runnable.start );
    System.out.println( runnable.end );
}

Avant d'utiliser ce modèle, veuillez évaluer si l'ancienne classe de niveau supérieur, ou classe interne, ou classe interne statique sont de meilleures alternatives.

 2
Author: Alexander Pogrebnyak, 2010-03-11 20:45:50

La principale raison de définir des classes internes (dans une méthode ou une classe) est de traiter l'accessibilité des membres et des variables de la classe et de la méthode englobantes. Une classe interne peut rechercher des membres de données privées et les exploiter. Si dans une méthode, il peut également traiter la variable locale finale.

Avoir des classes internes aide à s'assurer que cette classe n'est pas accessible au monde extérieur. Cela est vrai en particulier pour les cas de programmation d'interface utilisateur dans GWT ou GXT etc où JS génère le code est écrit en java et le comportement de chaque bouton ou événement doit être défini en créant des classes anonymes

 1
Author: Fazal, 2010-03-11 20:27:33