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.
- Quelle est l'utilité d'avoir une définition de classe dans une méthode?
- Un fichier de classe sera-t-il généré pour
DummyClass
- Il m'est difficile d'imaginer ce concept d'une manière orientée objet. Avoir une définition de classe dans un comportement. Quelqu'un peut probablement me dire avec des exemples équivalents dans le monde réel.
- Les classes abstraites à l'intérieur d'une méthode me semblent un peu folles. Mais aucune interface n'est autorisée. Y a-t-il une raison à cela?
java
class
local-class
bragboy
la source
la source
Réponses:
C'est ce qu'on appelle une classe locale.
2 est le plus simple: 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'aurez jamais besoin d'en instancier une ou de connaître les détails d'implémentation ailleurs que dans une seule 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:
Si vous deviez en créer un certain nombre et en faire quelque chose, vous pouvez changer cela en
En ce qui concerne les interfaces: je ne suis pas sûr qu'il y ait un problème technique qui fasse 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 ne devait être utilisée qu'à l'intérieur de la méthode, l'interface et la classe seraient implémentées dans cette méthode, donc la définition de l'interface serait redondante.
la source
parameter
précède peut être déclaré dans la méthode englobante et est accessible par les deux threads.Celles-ci sont appelées classes locales . Vous pouvez trouver une explication détaillée et un exemple ici . L'exemple renvoie une implémentation spécifique dont nous n'avons pas besoin de connaître en dehors de la méthode.
la source
La classe ne peut pas être vue (c'est-à-dire instanciée, ses méthodes accessibles sans Reflection) de l'extérieur de la méthode. De plus, il peut accéder aux variables locales définies dans testMethod (), mais avant la définition de la classe.
J'ai en fait pensé: "Aucun fichier de ce type ne sera écrit." jusqu'à ce que je viens de l'essayer: Oh oui, un tel fichier est créé! Il sera appelé quelque chose comme A $ 1B.class, où A est la classe externe et B est la classe locale.
Surtout pour les fonctions de rappel (gestionnaires d'événements dans les interfaces graphiques, comme onClick () lorsqu'un bouton est cliqué, etc.), il est assez courant 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 de constructeur sur elles. Dans ces cas, ces classes locales de méthodes peuvent être une bonne alternative.
la source
TestClass$1TestMethodClass.class
, analogue à la façon dont les.class
fichiers de classes internes sont nommés.Le vrai 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;)
la source
Le seul cas où vous souhaitez avoir une classe interne de fonctions complète par rapport à une classe anonyme (aka fermeture Java) est lorsque les conditions suivantes sont remplies
Par exemple, quelqu'un veut un
Runnable
et vous voulez enregistrer le début et la fin de l'exécution.Avec une classe anonyme, ce n'est pas possible, avec une classe interne, vous pouvez le faire.
Voici un exemple qui démontre mon point
Avant d'utiliser ce modèle, veuillez évaluer si une ancienne classe de premier niveau, une classe interne ou une classe interne statique sont de meilleures alternatives.
la source
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. Ceci est particulièrement vrai pour les cas de programmation d'interface utilisateur dans GWT ou GXT, etc. où le code de génération JS est écrit en java et le comportement de chaque bouton ou événement doit être défini en créant des classes anonymes
la source
Je suis tombé sur un bon exemple au printemps. Le cadre utilise le concept de définitions de classes locales à l'intérieur de la méthode pour traiter diverses opérations de base de données de manière uniforme.
Supposons que vous ayez un code comme celui-ci:
Regardons d'abord l'implémentation de execute ():
Veuillez noter la dernière ligne. Spring fait également cette "astuce" exacte pour le reste des méthodes:
Le "truc" avec les classes locales permet au framework de gérer tous ces scénarios dans une seule méthode qui accepte ces classes via l'interface StatementCallback. Cette méthode unique agit comme un pont entre les actions (exécuter, mettre à jour) et les opérations courantes autour d'elles (par exemple, exécution, gestion des connexions, traduction des erreurs et sortie de la console dbms)
la source