Jusqu'à J2SE1.4, il a été impossible de définir des méthodes avec des paramètres réels variables dans les programmes Java - car Java nécessite que le nombre et les types de paramètres réels (arguments) et les paramètres formels doivent être adaptés à un par un, et le nombre de paramètres formels est fixé lors de la définition de la méthode. Bien que la même méthode puisse être fournie avec un nombre différent de paramètres formels via le mécanisme de surcharge, cela ne peut toujours pas atteindre le but de permettre à la quantité réelle de paramètres de changer arbitrairement.
Cependant, la sémantique de certaines méthodes nécessite qu'ils doivent être en mesure d'accepter le nombre variable de paramètres réels - par exemple, la célèbre méthode principale doit être en mesure d'accepter tous les paramètres de ligne de commande en tant que paramètres réels, et le nombre de paramètres de ligne de commande ne peut pas être déterminé à l'avance.
Pour ce problème, traditionnellement, la pratique de «l'utilisation d'un tableau pour envelopper les paramètres réels à passer» est généralement utilisé pour y faire face.
1. Enveloppez les paramètres dans un tableau
La pratique des «paramètres réels enveloppés avec les tableaux» peut être divisé en trois étapes: d'abord, définissez un paramètre de type tableau pour cette méthode; Ensuite, lorsque vous appelez, générez un tableau contenant tous les paramètres réels à passer; Enfin, passez ce tableau en tant que paramètre réel.
Cette approche peut atteindre efficacement le but de «faire en sorte que la méthode accepte les paramètres variables», mais le formulaire lors de l'appel n'est pas assez simple.
Le mécanisme Varargs est fourni dans J2SE1.5, permettant une définition directe des paramètres formels qui peuvent correspondre à plusieurs paramètres réels. Ainsi, un nombre variable de paramètres réels peut être passé de manière plus simple.
La signification de varargs
D'une manière générale, "Varargs" signifie "variablembumber ofargments". Parfois, il est simplement appelé "variablearguments", mais parce que ce terme n'indique pas ce qui est variable, la signification est un peu vague.
2. Définissez une méthode avec des paramètres réels variables
Ajoutez simplement trois consécutifs "." (c'est-à-dire "...", une ellipse dans la phrase en anglais) entre le "type" et le "nom du paramètre" d'un paramètre formel, et il peut correspondre à un paramètre réel incertain. Une méthode avec de tels paramètres formels est une méthode avec des paramètres réels variables.
Listing 1: une méthode avec des paramètres réels variables
private static int sup (int ... valeurs) {}Notez que seul le dernier paramètre formel peut être défini comme "peut correspondre à un paramètre réel incertain". Par conséquent, il ne peut y avoir qu'un seul paramètre formel dans une méthode. De plus, si cette méthode a d'autres paramètres formels, placez-les en position avant.
Le compilateur convertira le dernier paramètre formel en un paramètre formel de tableau en secret et fera une marque dans le fichier de classe compilé pour indiquer qu'il s'agit d'une méthode avec des paramètres réels variables.
Listing 2: forme secrète d'une méthode avec des paramètres réels variables
private static int sup (int [] valeurs) {}En raison de telles transformations, il est impossible de définir une méthode pour cette classe cohérente avec la signature de la méthode convertie.
Listing 3: combinaisons qui entraîneront des erreurs de compilation
private static int sup (int ... valeurs) {} private static int sup (int [] valeurs) {}3. Appelez une méthode avec un nombre variable de paramètres réels
Tant que les paramètres réels à passer sont écrits un par un à la position correspondante, une méthode avec un nombre variable de paramètres réels peut être appelée. Aucune autre étape n'est requise.
Listing 4: plusieurs paramètres peuvent être passés
sumUp(1,3,5,7);
Indirectement, le compilateur convertira ce processus d'appel en la forme de "tableau enveloppé dans les paramètres réels":
Listing 5: Apparaissant secrètement Création du tableau
sumUp(newint[]{1,2,3,4});
De plus, le "incertain" mentionné ici comprend également zéro, donc un tel appel est raisonnable:
Listing 6: Vous pouvez également passer zéro paramètres réels
sumUp();
L'effet de cette méthode d'appel converti secrètement par le compilateur est équivalent à ceci:
Listing 7: zéro réel arguments correspondent à des tableaux vides
sumUp(newint[]{});
Notez que le passé est passé à ce moment, pas nul. Cela permet à une forme unifiée d'être gérée sans avoir à détecter à quelle situation il appartient.
4. Traitez les paramètres réels avec des nombres variables
La méthode de traitement des paramètres réels à nombre variable est essentiellement la même que la méthode de traitement des paramètres réels du tableau. Tous les paramètres réels sont enregistrés dans un tableau avec le même nom que les paramètres formels. Selon les besoins réels, après avoir lu les éléments de ce tableau, de la vapeur ou de la cuisson, vous pouvez faire ce que vous voulez.
Listing 8: traitement des arguments reçus
private static int sup (int ... valeurs) {int sum = 0; pour (int i = 0; i <valeurs.length; i ++) {sum + = valeurs [i]; } Retour Sum;}5. Transférer le nombre variable de paramètres
Parfois, après avoir accepté un ensemble de paramètres de nombre variable, ils doivent être transmis à une autre méthode de nombre variable. Parce que le nombre de paramètres réels reçus lors de l'encodage ne peut pas être connu, la pratique de "les écrire un par un à l'endroit où ils devraient apparaître" n'est pas possible. Cependant, cela ne signifie pas qu'il s'agit d'une tâche ininstatable, car il existe une autre façon d'appeler une méthode avec des paramètres réels variables.
Aux yeux du compilateur J2SE1.5, la méthode avec des paramètres réels variables est un cas particulier de la méthode avec un tableau de paramètres formels à la fin. Par conséquent, placez l'ensemble entier de paramètres réels à passer dans un tableau à l'avance, puis passez ce tableau comme dernier paramètre réel à une méthode avec un nombre variable de paramètres réels, qui ne provoquera aucune erreur. Avec cette fonctionnalité, le transfert peut être terminé en douceur.
Listing 9: transfert des paramètres réels reçus
classe publique printfsample {public static void main (String [] args) {printout ("pi:% f e:% f / n", math.pi, math.e); } private static void Printout (Format de chaîne, objet ... args) {System.out.printf (format, args); }}6. Est-ce un tableau? Pas un tableau?
Bien que dans les coulisses, le compilateur convertira des paramètres formels qui peuvent correspondre aux paramètres réels incertains en paramètres formels du tableau; et il peut également utiliser un tableau pour envelopper les paramètres réels, puis les transmettre à une méthode avec un nombre variable de paramètres réels; Cependant, cela ne signifie pas qu'il n'y a pas de différence entre "les paramètres formels qui peuvent correspondre aux paramètres réels incertains" et "paramètres formels du tableau".
Une différence évidente est que si vous appelez une méthode dont le dernier paramètre formel est un paramètre formel du tableau sous la forme d'une méthode avec un nombre variable de paramètres réels, il ne conduira qu'à une erreur de compilation "ne peut pas appliquer".
Listing 10: une erreur de compilation pour "ne peut pasBeAppliedto"
STATIC VOID TESTOROTOLOTOLING (int [] i) {System.out.println ("A");} public static void main (String [] args) {testoVoLoting (1, 2, 3); // Erreur de compilation}}Pour cette raison, cette méthode d'appel concise ne peut pas être directement adoptée lors de l'appel des méthodes qui ne prennent en charge que les paramètres réels d'emballage avec des tableaux (par exemple, ceux qui sont restés à partir de conceptions de bibliothèque tierces pour J2SE1.5).
Si vous ne pouvez pas modifier la classe d'origine et ajouter une version variable du nombre de paramètres à la méthode à appeler, et que vous souhaitez adopter cette méthode d'appel concise, vous pouvez utiliser les méthodes de reconstruction de "introduporeignmethod" et "introducelocalextension" pour approximer l'objectif.
7. Lorsqu'un nombre variable d'arguments rencontre un générique
Un nouveau mécanisme "générique" a été ajouté à J2SE1.5, qui peut paramétrer un type dans certaines conditions. Par exemple, lors de l'écriture d'une classe, le type de paramètres formels d'une méthode peut être représenté par un identifiant (tel que t). Quant à quel type cet identifiant représente, il est spécifié lors de la génération d'une instance de cette classe. Ce mécanisme peut être utilisé pour fournir une réutilisation de code plus complète et une vérification de type de temps de compilation plus stricte.
Cependant, le mécanisme générique ne peut pas être utilisé avec des nombres variables de paramètres formels. Si un type de paramètre formel qui correspond à un argument incertain est représenté par un identifiant, le compilateur donnera une erreur de "généricarraycréation".
Listing 11: lorsque Varargs rencontre les génériques
TestVarargs de Void statique privé (t ... args) {// Erreur de compilation}La raison de ce phénomène est une contrainte inhérente du mécanisme générique dans J2SE1.5 - Une instance de ce type ne peut pas être créée avec le type représenté par un identifiant. Avant la prise en charge de la version Java sans que cette contrainte n'apparaisse, il n'y avait essentiellement aucune bonne solution à ce problème.
Cependant, la pratique traditionnelle des "tableaux enveloppants" n'est pas soumise à cette contrainte.
Listing 12: solutions de contournement compilables
private static void testvarargs (t [] args) {for (int i = 0; i <args.length; i ++) {System.out.println (args [i]); }}8. Problèmes de sélection en surcharge
Java prend en charge les mécanismes de "surcharge", permettant à de nombreuses méthodes différentes de la même classe d'avoir uniquement des listes de paramètres formels. Ensuite, le compilateur sélectionne la méthode à exécuter en fonction des paramètres réels au moment de l'appel.
Les choix traditionnels sont essentiellement basés sur le principe des «personnes spéciales sont préférées». La spécialité d'une méthode dépend du nombre de conditions qui doivent être remplies pour qu'il fonctionne bien. Plus vous avez besoin de conditions, plus elle est spéciale.
Après l'introduction du mécanisme Varargs, ce principe s'applique toujours, mais les problèmes à considérer sont enrichis - traditionnellement, parmi les différentes versions d'une méthode surchargée, seuls ceux dont les paramètres morphologiques et les paramètres réels sont exactement les mêmes sont éligibles à une considération supplémentaire. Cependant, après l'introduction du mécanisme Varargs, il est possible de correspondre aux deux versions, et il n'y a pas de différence dans d'autres aspects, juste qu'un paramètre réel a un nombre fixe et l'autre paramètre réel a un nombre variable.
Dans ce cas, la règle de détermination utilisée est que "la version avec un nombre fixe de paramètres réels a priorité sur la version avec un nombre variable de paramètres réels".
Listing 13: les versions avec un nombre fixe de paramètres réels sont préférés
Si, dans la vue du compilateur, plusieurs méthodes ont la même priorité, elle sera coincée dans un état où il ne peut pas faire de choix sur la méthode à appeler. Dans ce cas, il générera une erreur de compilation de "référence appelé le nom de la méthode est ambigu" et attendra patiemment que certaines modifications pour éviter l'arrivée du nouveau code source déroutant.
Après l'introduction du mécanisme Varargs, cette situation qui peut entraîner une confusion a augmenté un peu plus. Par exemple, il peut y avoir deux versions qui peuvent correspondre, ce qui est exactement le même dans d'autres aspects, et les deux conflits avec des nombres variables de paramètres réels se produisent.
Classe publique Overloadingsamplea {public static void main (String [] args) {testoLtoLing (1); // imprimez AtestoLoting (1, 2); // imprimez BtestoVoLoting (1, 2, 3); // imprime C} privé Static Void TestOploading (int i) {System.out.println ("a" a "); j) {System.out.println ("b");} private static void testOletoLing (int i, int ... plus) {System.out.println ("c");}}Si, dans la vue du compilateur, plusieurs méthodes ont la même priorité, elle sera coincée dans un état où il ne peut pas faire de choix sur la méthode à appeler. Dans ce cas, il générera une erreur de compilation de "référence appelé le nom de la méthode est ambigu" et attendra patiemment que certaines modifications pour éviter l'arrivée du nouveau code source déroutant.
Après l'introduction du mécanisme Varargs, cette situation qui peut entraîner une confusion a augmenté un peu plus. Par exemple, il peut y avoir deux versions qui peuvent correspondre, ce qui est exactement le même dans d'autres aspects, et les deux conflits avec des nombres variables de paramètres réels se produisent.
Listing 14: Quoi qu'il en soit, il est difficile pour le compilateur d'être
classe publique OverloadingsampleB {public static void main (String [] args) {testoVoLoting (1, 2, 3); // Erreur de compilation} Private Static Void TestOtORORDING (Object ... Args) {}}De plus, comme le mécanisme "Autoboxing / Auto-Unboxing" dans J2SE1.5, il est possible que les deux versions puissent correspondre, et le nombre de paramètres réels est variable, et les autres aspects sont exactement les mêmes. C'est juste qu'un paramètre réel acceptable est le type de base, tandis que l'autre paramètre réel acceptable est le conflit entre la classe de package.
Listing 15: Nouveaux numéros de l'autoboxing / auto-unboxing
classe publique Overloadingsamplec {public static void main (String [] args) {/ * Erreur de compilation * / TestOverloading (1, 2); / * ou compiler l'erreur * / Testoverloading (nouvel entier (1), nouvel entier (2));} TestOrtOrding STATIC privé.9. Résumé
Par rapport à la méthode "enveloppée avec des tableaux", la méthode réelle avec des paramètres réels variables est plus simple et a des significations plus claires lors de l'appel. Cependant, ce mécanisme a également ses propres limites et n'est pas une solution parfaite.
Ce qui précède est toute l'explication détaillée du code des paramètres de longueur variable en Java, j'espère que cela sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à ce site:
Explication détaillée des paramètres implicites et des instances de paramètres d'affichage en java
Implémentation de programmation Java du code rapide et du code d'optimisation Explication détaillée
Java Encryption Decryption and Digital Signature Complete Code Exemple
S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!