Bis J2SE1.4 war es unmöglich, Methoden mit variablen realen Parametern in Java -Programmen zu definieren - da Java die Anzahl und die Arten von realen Parametern (Argumenten) und formale Parameter nacheinander übereinstimmen müssen, und die Anzahl der formalen Parameter bei der Definition der Methode festgelegt wird. Obwohl dieselbe Methode mit einer anderen Anzahl formaler Parameter durch den Überlastmechanismus bereitgestellt werden kann, kann dies dennoch nicht den Zweck erreichen, die reale Parametermenge willkürlich zu ändern.
Die Semantik einiger Methoden erfordern jedoch, dass sie in der Lage sein müssen, eine variable Anzahl der tatsächlichen Parameter zu akzeptieren. Beispielsweise muss die berühmte Hauptmethode in der Lage sein, alle Befehlszeilenparameter als tatsächliche Parameter zu akzeptieren, und die Anzahl der Befehlszeilenparameter kann nicht im Voraus ermittelt werden.
Für dieses Problem wird traditionell die Praxis, "ein Array zu verwenden, um die tatsächlichen Parameter zu übergeben", im Allgemeinen verwendet, um damit umzugehen.
1. Wickeln Sie die Parameter in ein Array ein
Die Praxis von "tatsächlichen Parametern mit Arrays" kann in drei Schritte unterteilt werden: Definieren Sie zuerst einen Array-Parameter für diese Methode; Generieren Sie dann, wenn Sie aufgerufen werden, ein Array, das alle tatsächlichen Parameter enthält, die übergeben werden sollen. Übergeben Sie dieses Array schließlich als realer Parameter.
Dieser Ansatz kann effektiv den Zweck erreichen, "die Methode zu variablen Parametern akzeptieren", aber das Formular beim Aufrufen ist nicht einfach genug.
Der Varargs -Mechanismus ist in J2SE1.5 bereitgestellt, die eine direkte Definition formaler Parameter ermöglichen, die mehrere reale Parameter übereinstimmen können. Somit kann eine variable Anzahl der tatsächlichen Parameter einfacher übergeben werden.
Die Bedeutung von Varargs
Im Allgemeinen bedeutet "Varargs" "VariablNumberOfarguments". Manchmal wird es einfach als "Varibleargumente" bezeichnet, aber da dieser Begriff nicht angibt, was variabel ist, ist die Bedeutung ein wenig vage.
2. Definieren Sie eine Methode mit variablen realen Parametern
Fügen Sie einfach drei aufeinanderfolgende "" hinzu. " (d.h. Eine Methode mit solchen formalen Parametern ist eine Methode mit variablen realen Parametern.
Listing 1: Eine Methode mit variablen realen Parametern
private static int sumup (int ... values) {}Beachten Sie, dass nur der letzte formale Parameter definiert werden kann als "mit einem unsicheren tatsächlichen Parameter übereinstimmen". Daher kann es in einer Methode nur einen solchen formalen Parameter geben. Wenn diese Methode andere formale Parameter aufweist, stellen Sie sie außerdem in die vordere Position.
Der Compiler konvertiert den letzten formalen Parameter in einem Array -formalen Parameter im Geheimen und markiert in der kompilierten Klassendatei eine Marke, um anzuzeigen, dass dies eine Methode mit variablen realen Parametern ist.
Listing 2: Geheime Form einer Methode mit variablen realen Parametern
private static int sumup (int [] Werte) {}Aufgrund solcher Transformationen ist es unmöglich, eine Methode für diese Klasse zu definieren, die mit der konvertierten Methodensignatur übereinstimmt.
Listing 3: Kombinationen, die Kompilierungsfehler verursachen
private static int sumup (int ... values) {} private statische int sumup (int [] Werte) {}3. Rufen Sie eine Methode mit variabler Anzahl realer Parameter auf
Solange die zu übergebenen tatsächlichen Parameter einzeln in die entsprechende Position geschrieben werden, kann eine Methode mit variabler Anzahl realer Parameter aufgerufen werden. Es sind keine weiteren Schritte erforderlich.
Listing 4: Mehrere Parameter können übergeben werden
sumUp(1,3,5,7);
Indirekt wird der Compiler diesen Aufrufprozess in die Form von "Array in tatsächlichen Parametern" umwandeln:
Listing 5: Heim erscheinen Array -Erstellung
sumUp(newint[]{1,2,3,4});
Darüber hinaus enthält der hier erwähnte "Unsichere" ebenfalls Null, daher ist ein solcher Anruf angemessen:
Listing 6: Sie können auch Null -tatsächliche Parameter übergeben
sumUp();
Die Auswirkung dieser aufrufenden Methode, die vom Compiler heimlich konvertiert wird, entspricht der Folge:
Listing 7: Null reale Argumente entsprechen leeren Arrays
sumUp(newint[]{});
Beachten Sie, dass die Vergangenheit zu diesem Zeitpunkt überschritten wird, nicht null. Dies ermöglicht eine einheitliche Form, ohne zu erkennen, zu welcher Situation sie gehört.
4. Verarbeiten Sie die tatsächlichen Parameter mit variablen Zahlen
Die Methode zur Verarbeitung von tatsächlichen Parametern der variablen zahlreichen Verarbeitung entspricht im Grunde genommen der Methode der Verarbeitung der tatsächlichen Parameter. Alle tatsächlichen Parameter werden in einem Array mit demselben Namen wie die formalen Parameter gespeichert. Nach den tatsächlichen Bedürfnissen können Sie nach dem Lesen der Elemente in diesem Array, dampfen oder kochen, was Sie wollen.
Listing 8: Bearbeitung der empfangenen Argumente
private static int sumup (int ... values) {int sum = 0; für (int i = 0; i <values.length; i ++) {sum+= values [i]; } return sum;}5. Leiten Sie die variable Anzahl der Parameter weiter
Nach Annahme einer Reihe von Variablenzahlparametern müssen sie manchmal an eine andere Methode zur Variablenzahlen übergeben werden. Da die Anzahl der tatsächlichen Parameter, die während der Codierung empfangen werden, nicht bekannt werden kann, ist die Praxis, sie einzeln zu schreiben, an den Ort, an dem sie erscheinen sollten "nicht möglich. Dies bedeutet jedoch nicht, dass dies eine unvollständige Aufgabe ist, da es eine andere Möglichkeit gibt, eine Methode mit variablen realen Parametern aufzurufen.
In den Augen des J2SE1.5 -Compilers ist die Methode mit variablen realen Parametern ein Sonderfall der Methode mit einer Reihe formaler Parameter am Ende. Setzen Sie daher den gesamten Satz der tatsächlichen Parameter vor, die im Voraus in ein Array übergeben werden sollen, und übergeben Sie dieses Array dann als der letzte tatsächliche Parameter an eine Methode mit variabler Anzahl realer Parameter, was keine Fehler verursacht. Mit dieser Funktion kann die Weiterleitung reibungslos abgeschlossen werden.
Listing 9: Weiterleiten der empfangenen tatsächlichen Parameter
public class printfsample {public static void main (String [] args) {printout ("pi:%f e:%f/n", math.pi, math.e); } private static void printout (String -Format, Objekt ... args) {System.out.printf (Format, args); }}6. Ist es ein Array? Kein Array?
Obwohl der Compiler hinter den Kulissen formale Parameter umwandelt, die unsichere reale Parameter in die formalen Array -Parameter übereinstimmen können. und es kann auch ein Array verwenden, um die tatsächlichen Parameter einzuwickeln und sie dann an eine Methode mit variabler Anzahl realer Parameter zu übergeben. Dies bedeutet jedoch nicht, dass es keinen Unterschied zwischen "den formalen Parametern gibt, die unsichere reale Parameter" und "Array -formale Parameter" übereinstimmen können.
Ein offensichtlicher Unterschied besteht darin, dass, wenn Sie eine Methode aufrufen, deren letzter formaler Parameter ein formeller Array -Parameter in Form einer Methode mit variabler Anzahl realer Parameter ist, nur zu einem Kompilierungsfehler "Kann nicht" nicht mehrfach "geführt werden.
Listing 10: Ein Kompilierungsfehler für "kann nichtBeAppliedto"
private static void testoverading (int [] i) {System.out.println ("a");} öffentliche statische void main (String [] args) {testoverading (1, 2, 3); // Kompilierungsfehler}Aus diesem Grund kann diese kurze Anrufmethode nicht direkt angewendet werden, wenn Methoden aufgerufen werden, die nur das Verpackung tatsächlicher Parameter mit Arrays unterstützen (z. B. diejenigen, die aus Bibliotheksdesigns von Drittanbietern für J2SE1.5 übrig sind).
Wenn Sie die ursprüngliche Klasse nicht ändern und einer aufgerufenen Methode eine variable Version der Anzahl der Parameter hinzufügen können, und Sie diese präzise Aufrufmethode anwenden möchten, können Sie die Rekonstruktionsmethoden von "IntrocesforeNienMethod" und "Introcelocalextesion" verwenden, um den Zweck zu approximieren.
7. Wenn eine variable Anzahl von Argumenten auf einen generischen Begriff stößt
J2SE1.5 wurde ein neuer "generischer" Mechanismus hinzugefügt, der einen Typ unter bestimmten Bedingungen parametrisieren kann. Zum Beispiel kann beim Schreiben einer Klasse der formelle Parameter einer Methode durch eine Kennung (wie T) dargestellt werden. Was diese Kennung angeht, wird er beim Generieren einer Instanz dieser Klasse angegeben. Dieser Mechanismus kann verwendet werden, um eine umfassendere Wiederverwendung von Code und strengere Kompilierungs-Zeit-Typ-Überprüfung bereitzustellen.
Der generische Mechanismus kann jedoch nicht mit variablen Anzahl formaler Parameter verwendet werden. Wenn ein formaler Parametertyp, der einem ungewisse Argument entspricht, durch eine Kennung dargestellt wird, gibt der Compiler einen "genericArraycreation" -Fehler an.
Listing 11: Wenn Varargs Generika erfüllt
private statische void testvarargs (t ... args) {// Kompilierungsfehler}Der Grund für dieses Phänomen ist eine inhärente Einschränkung des generischen Mechanismus in J2SE1.5 - eine Instanz dieses Typs kann nicht erstellt werden, mit dem Typ, der durch eine Kennung dargestellt wird. Bevor die Java -Version ohne diese Einschränkung auftrat, gab es im Grunde keine gute Lösung für dieses Problem.
Die traditionelle "Wrap With Arrays" -Praxis unterliegt jedoch nicht dieser Einschränkung.
Listing 12: Kompilierbare Problemumgehungen
private statische void testvarargs (t [] args) {für (int i = 0; i <argsgth; i ++) {System.out.println (args [i]); }}8. Auswahlprobleme bei der Überlastung
Java unterstützt "Überladungs" -Mechanismen und ermöglicht es vielen verschiedenen Methoden in derselben Klasse, nur Listen formaler Parameter zu haben. Anschließend wählt der Compiler aus, welche Methode basierend auf den tatsächlichen Parametern zum Zeitpunkt des Klangs ausführen soll.
Traditionelle Entscheidungen basieren im Grunde auf dem Prinzip "besondere Menschen werden bevorzugt". Die Spezialität einer Methode hängt von der Anzahl der Bedingungen ab, die erfüllt werden müssen, damit sie reibungslos ausgeführt werden kann. Je mehr Bedingungen Sie brauchen, desto besonderer ist es.
Nach der Einführung des Varargs -Mechanismus gilt dieses Prinzip weiterhin, aber die zu berücksichtigenden Probleme werden angereichert - traditionell unter den verschiedenen Versionen einer überlasteten Methode sind nur diejenigen, deren morphologische Parameter und reale Parameter genau gleich sind, für weitere Berücksichtigung berechtigt. Nach der Einführung des Varargs -Mechanismus ist es jedoch möglich, beide Versionen zu entsprechen, und es gibt keinen Unterschied in anderen Aspekten, nur dass ein realer Parameter eine feste Zahl hat und der andere reale Parameter eine variable Zahl hat.
In diesem Fall ist die verwendete Bestimmungsregel: "Die Version mit fester Anzahl realer Parameter hat Vorrang gegenüber der Version mit variabler Anzahl realer Parameter".
Listing 13: Versionen mit fester Anzahl realer Parameter werden bevorzugt
Wenn mehrere Methoden nach Ansicht des Compilers die gleiche Priorität haben, steckt es in einem Zustand, in dem es keine Wahl darüber treffen kann, welche Methode aufgerufen werden soll. In diesem Fall wird ein Kompilierungsfehler von "Referenceto bezeichnet, der als Methodenname issambiguieren" bezeichnet wird, und warten geduldig auf einige Änderungen, um die Ankunft des neuen Quellcodes zu vermeiden, der verwirrend ist.
Nach der Einführung des Varargs -Mechanismus hat diese Situation, die zu Verwirrung führen kann, etwas mehr zugenommen. Zum Beispiel können es zwei Versionen geben, die übereinstimmen können, was genau in anderen Aspekten gleich ist, und beide Konflikte mit variablen Anzahl realer Parameter treten auf.
öffentliche Klasse OverloadingSsampea {public static void main (String [] args) {testoverloading (1); // Ausdrucken Sie die Bekämpfung von Betrüger (1, 2); // BTestoverloading ausdrucken (1, 2, 3); // drucken Sie C} private statische void -statische statische Struktur (int i). j) {System.out.println ("B");} private statische void testoverloading (int i, int ... more) {System.out.println ("C");}}Wenn mehrere Methoden nach Ansicht des Compilers die gleiche Priorität haben, steckt es in einem Zustand, in dem es keine Wahl darüber treffen kann, welche Methode aufgerufen werden soll. In diesem Fall wird ein Kompilierungsfehler von "Referenceto bezeichnet, der als Methodenname issambiguieren" bezeichnet wird, und warten geduldig auf einige Änderungen, um die Ankunft des neuen Quellcodes zu vermeiden, der verwirrend ist.
Nach der Einführung des Varargs -Mechanismus hat diese Situation, die zu Verwirrung führen kann, etwas mehr zugenommen. Zum Beispiel können es zwei Versionen geben, die übereinstimmen können, was genau in anderen Aspekten gleich ist, und beide Konflikte mit variablen Anzahl realer Parameter treten auf.
Listing 14: Egal was passiert, es fällt dem Compiler schwer zu sein
öffentliche Klasse OverloadingSampleB {public static void main (String [] args) {testoverloading (1, 2, 3); // Kompilierungsfehler} private statische Void TestOverading (Objekt ... Args) {}}Da es in J2SE1.5 den Mechanismus "Autoboxing/Auto-Unboxing" gibt, ist es möglich, dass beide Versionen übereinstimmen und die Anzahl der realen Parameter variabel ist und die anderen Aspekte genau gleich sind. Es ist nur so, dass ein akzeptabler realer Parameter der Grundtyp ist, während der andere akzeptable reale Parameter der Konflikt zwischen der Paketklasse ist.
Listing 15: Neue Probleme aus Autoboxing/Auto-Unboxing
public class OverloadingSsampec {public static void main (String [] args) {/* Kompilierungsfehler*/testoverloading (1, 2);/* oder kompilieren Sie Fehler*/testoverloading (New Integer (1), neu Integer (2));9. Zusammenfassung
Im Vergleich zur Methode "With With With With Arrays" ist die reale Methode mit variablen realen Parametern einfacher und hat beim Aufrufen klarer. Dieser Mechanismus hat jedoch auch seine eigenen Einschränkungen und ist keine perfekte Lösung.
Das obige ist die detaillierte Erläuterung des Parametercodes der variablen Länge in Java. Ich hoffe, er wird für alle hilfreich sein. Interessierte Freunde können weiterhin auf diese Seite verweisen:
Detaillierte Erläuterung implizite Parameter und Anzeigeparameterinstanzen in Java
Java -Programmierungsimplementierung von Schnellsortierungs- und Optimierungscode Detaillierte Erläuterung
Java -Verschlüsselung Entschlüsselung und digitale Signatur vollständiger Code -Beispiel
Wenn es Mängel gibt, hinterlassen Sie bitte eine Nachricht, um darauf hinzuweisen. Vielen Dank an Freunde für Ihre Unterstützung für diese Seite!