webentwicklung-frage-antwort-db.com.de

Wann verwenden Sie Varargs in Java?

Ich habe Angst vor Varargs. Ich weiß nicht, wofür ich sie verwenden soll.

Außerdem ist es gefährlich, die Leute so viele Argumente weitergeben zu lassen, wie sie wollen.

Was ist ein Beispiel für einen Kontext, der ein guter Ort wäre, um sie zu nutzen?

189
Harry Quince

Varargs sind nützlich für jede Methode, die mit einer unbestimmten Anzahl von Objekten umgehen muss. Ein gutes Beispiel ist String.format . Die Formatzeichenfolge kann eine beliebige Anzahl von Parametern annehmen, sodass Sie einen Mechanismus zum Übergeben einer beliebigen Anzahl von Objekten benötigen.

String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
150
Andy White

Eine gute Faustregel wäre:

"Verwenden Sie varargs für jede Methode (oder jeden Konstruktor), die ein Array von T (welcher Typ auch immer T sein mag) als Eingabe benötigt".

Dies erleichtert den Aufruf dieser Methoden (es ist nicht erforderlich new T[]{...}).

Sie können diese Regel erweitern, um Methoden mit einem Argument List<T> Einzuschließen, vorausgesetzt, dieses Argument ist nur für die Eingabe vorgesehen (dh, die Liste wird von der Methode nicht geändert).

Außerdem würde ich auf die Verwendung von f(Object... args) verzichten, da dies zu einer Programmierweise mit unklaren APIs führt.

In Beispielen habe ich es in DesignGridLayout verwendet, wo ich mehrere JComponents in einem Aufruf hinzufügen kann:

layout.row().grid(new JLabel("Label")).add(field1, field2, field3);

Im obigen Code ist die add () -Methode als add(JComponent... components) definiert.

Schließlich muss bei der Implementierung solcher Methoden darauf geachtet werden, dass sie mit einem leeren vararg aufgerufen werden können! Wenn Sie mindestens ein Argument vorbringen möchten, müssen Sie einen hässlichen Trick anwenden, wie zum Beispiel:

void f(T arg1, T... args) {...}

Ich halte diesen Trick für hässlich, da die Implementierung der Methode weniger einfach ist, als nur T... args In der Argumentliste zu haben.

Hoffe, dass dies hilft, den Punkt über Varargs zu klären.

78
jfpoilpret

Ich verwende varargs häufig für die Ausgabe in die Protokolle zum Debuggen.

So ziemlich jede Klasse in meiner App hat eine Methode debugPrint ():

private void debugPrint(Object... msg) {
    for (Object item : msg) System.out.print(item);
    System.out.println();
}

Dann habe ich innerhalb der Methoden der Klasse Aufrufe wie die folgenden:

debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
    serialNo, ", the grade is ", grade);

Wenn ich zufrieden bin, dass mein Code funktioniert, kommentiere ich den Code in der debugPrint () -Methode aus, damit die Protokolle nicht zu viele überflüssige und unerwünschte Informationen enthalten, aber ich kann die einzelnen Aufrufe von debugPrint () unkommentiert lassen. Wenn ich später einen Fehler finde, kommentiere ich einfach den debugPrint () -Code aus und alle meine Aufrufe von debugPrint () werden reaktiviert.

Natürlich könnte ich genauso gut auf Varianz verzichten und stattdessen Folgendes tun:

private void debugPrint(String msg) {
    System.out.println(msg);
}

debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
    + serialNo + ", the grade is " + grade);

Wenn ich in diesem Fall den debugPrint () -Code auskommentiere, muss der Server immer noch die Mühe machen, alle Variablen in jedem Aufruf von debugPrint () zu verketten, obwohl mit der resultierenden Zeichenfolge nichts getan wird. Wenn ich jedoch varargs verwende, muss der Server sie nur in ein Array einfügen, bevor er erkennt, dass er sie nicht benötigt. Es wird viel Zeit gespart.

34
bob

Varargs können verwendet werden, wenn wir uns nicht sicher sind, wie viele Argumente in einer Methode übergeben werden sollen. Im Hintergrund wird ein Array von Parametern von nicht angegebener Länge erstellt, und ein solcher Parameter kann zur Laufzeit als Array behandelt werden.

Wenn wir eine Methode haben, die überladen ist, um eine andere Anzahl von Parametern zu akzeptieren, können wir statt der Überladung der Methode zu verschiedenen Zeiten einfach das varargs-Konzept verwenden.

Auch wenn sich der Parametertyp ändert, vereinfacht die Verwendung von "Object ... test" den Code erheblich.

Beispielsweise:

public int calculate(int...list) {
    int sum = 0;
    for (int item : list) {
        sum += item;
    }
    return sum;
}

Hier wird indirekt ein Array vom Typ int (Liste) als Parameter übergeben und im Code als Array behandelt.

Zum besseren Verständnis folgen Sie diesem Link (es hat mir sehr geholfen, dieses Konzept klar zu verstehen): http://www.javadb.com/using-varargs-in-Java

PS: Sogar ich hatte Angst, Varargs zu benutzen, wenn ich es nicht wusste. Aber jetzt bin ich daran gewöhnt. Wie es heißt: "Wir klammern uns an das Bekannte, haben Angst vor dem Unbekannten", also benutze es so oft du kannst und du wirst es auch mögen :)

12
Sarvan

Varargs ist die Funktion, die in Java Version 1.5 hinzugefügt wurde.

Warum dies verwenden?

  1. Was ist, wenn Sie nicht wissen, wie viele Argumente für eine Methode übergeben werden müssen?
  2. Was ist, wenn Sie einer Methode eine unbegrenzte Anzahl von Argumenten übergeben möchten?

Wie funktioniert das?

Es erstellt ein Array mit den angegebenen Argumenten und übergibt das Array an die Methode.

Beispiel:

public class Solution {



    public static void main(String[] args) {
        add(5,7);
        add(5,7,9);
    }

    public static void add(int... s){
        System.out.println(s.length);
        int sum=0;
        for(int num:s)
            sum=sum+num;
        System.out.println("sum is "+sum );
    }

}

Ausgabe :

2

summe ist 12

3

summe ist 21

11
Arun Prakash

Ich habe auch Angst vor Varietäten:

Wenn der Aufrufer ein explizites Array an die Methode übergibt (im Gegensatz zu mehreren Parametern), erhalten Sie einen gemeinsamen Verweis auf dieses Array.

Wenn Sie dieses Array intern speichern müssen, möchten Sie es möglicherweise zuerst klonen, damit der Aufrufer es später nicht ändern kann.

 Object[] args = new Object[] { 1, 2, 3} ;

 varArgMethod(args);  // not varArgMethod(1,2,3);

 args[2] = "something else";  // this could have unexpected side-effects

Dies unterscheidet sich zwar nicht wirklich von der Übergabe von Objekten, deren Status sich später ändern könnte, da das Array normalerweise (im Fall eines Aufrufs mit mehreren Argumenten anstelle eines Arrays) ein vom Compiler intern neu erstelltes Array ist, das Sie ohne Bedenken erstellen können verwenden, ist dies sicherlich unerwartetes Verhalten.

5
Thilo

Ich verwende varargs häufig für Konstruktoren, die eine Art Filterobjekt aufnehmen können. Beispielsweise basiert ein großer Teil unseres auf Hadoop basierenden Systems auf einem Mapper, der die Serialisierung und Deserialisierung von Elementen für JSON übernimmt. Er wendet eine Reihe von Prozessoren an, die jeweils ein Inhaltselement übernehmen und es entweder ändern und zurückgeben oder null zurückgeben ablehnen.

1
Kevin Peterson

In Java doc von Var-Args ist die Verwendung von var-args ziemlich klar:

http://docs.Oracle.com/javase/1.5.0/docs/guide/language/varargs.html

über die Verwendung heißt es:

"Wann sollten Sie also varargs verwenden? Als Client sollten Sie sie immer dann nutzen, wenn die API sie anbietet. Wichtige Verwendungszwecke in Kern-APIs sind Reflexion, Nachrichtenformatierung und die neue printf-Funktion. Als API-Designer sollten Sie sie verwenden sparsam, nur wenn der Nutzen wirklich überzeugend ist. Im Allgemeinen sollten Sie eine varargs-Methode nicht überladen, da es sonst für Programmierer schwierig wird, herauszufinden, welche Überladung aufgerufen wird. "

1
Surendra