varargsが怖いです。何に使うかわかりません。
さらに、人々が望むだけ多くの議論を通過させることは危険だと感じます。
それらを使用するのに適したコンテキストの例は何ですか?
varargsが怖いです。何に使うかわかりません。
さらに、人々が望むだけ多くの議論を通過させることは危険だと感じます。
それらを使用するのに適したコンテキストの例は何ですか?
回答:
Varargsは、不確定な数のオブジェクトを処理する必要があるすべてのメソッドに役立ちます。良い例が1つですString.format
。フォーマット文字列は任意の数のパラメーターを受け入れることができるため、任意の数のオブジェクトを渡すメカニズムが必要です。
String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
大まかな目安は次のとおりです。
「入力としてTの配列(T型が何であれ)を必要とするメソッド(またはコンストラクター)には可変引数を使用します。
これにより、これらのメソッドの呼び出しが簡単になります(実行する必要はありません) new T[]{...}
)。
このルールを拡張して、 List<T>
引数をます。ただし、この引数が入力専用である場合(つまり、リストがメソッドによって変更されない場合)。
さらに、私は使用を控えます f(Object... args)
APIが不明確なプログラミング方法に陥ってしまうため、ます。
例として、DesignGridLayoutで使用しました。1回JComponent
の呼び出しで複数のを追加できます。
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
上記のコードでは、add()メソッドは次のように定義されています。 add(JComponent... components)
ます。
最後に、そのようなメソッドの実装は、空の可変引数で呼び出される可能性があるという事実に注意する必要があります!少なくとも1つの引数を課したい場合は、次のような醜いトリックを使用する必要があります。
void f(T arg1, T... args) {...}
メソッドの実装は、 T... args
引数リストにあるています。
これが可変引数に関する要点を明確にするのに役立つことを願っています。
if (args.length == 0) throw new RuntimeException("foo");
代わりに前提条件チェックを追加することを検討しましたか?(呼び出し側が契約に違反していたため)
void f(T arg1, T... args)
実行時まで待機する必要なく、常に引数なしで呼び出されることがないようにすることをお勧めします。
デバッグの目的でログに出力するためにvarargsを頻繁に使用しています。
アプリのほぼすべてのクラスにdebugPrint()メソッドがあります。
private void debugPrint(Object... msg) {
for (Object item : msg) System.out.print(item);
System.out.println();
}
次に、クラスのメソッド内で、次のような呼び出しがあります。
debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
serialNo, ", the grade is ", grade);
コードが機能していることを確認したら、debugPrint()メソッドのコードをコメント化して、ログに無関係で不要な情報が多く含まれないようにしますが、debugPrint()への個々の呼び出しはコメント化しないでおくことができます。後でバグを見つけたら、debugPrint()コードのコメントを外すだけで、debugPrint()へのすべての呼び出しが再びアクティブになります。
もちろん、varargsを簡単に回避して、代わりに次のようにすることもできます。
private void debugPrint(String msg) {
System.out.println(msg);
}
debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
+ serialNo + ", the grade is " + grade);
ただし、この場合、debugPrint()コードをコメントアウトすると、サーバーは、結果の文字列で何も行われなくても、debugPrint()を呼び出すたびにすべての変数を連結するという問題を経験する必要があります。ただし、可変引数を使用する場合、サーバーはそれらを必要としないことに気付く前に、それらを配列に入れるだけで済みます。多くの時間が節約されます。
メソッドで渡される引数の数がわからない場合は、可変引数を使用できます。それはバックグラウンドで不特定の長さのパラメータの配列を作成し、そのようなパラメータは実行時に配列として扱うことができます。
異なる数のパラメーターを受け入れるためにオーバーロードされるメソッドがある場合、メソッドを異なる時間にオーバーロードする代わりに、varargsコンセプトを使用できます。
また、パラメーターのタイプが異なる場合は、「Object ... test」を使用するとコードが大幅に簡略化されます。
例えば:
public int calculate(int...list) {
int sum = 0;
for (int item : list) {
sum += item;
}
return sum;
}
ここでは、間接的にint型(リスト)の配列がパラメーターとして渡され、コードでは配列として扱われます。
理解を深めるには、次のリンクに従ってください(この概念を明確に理解するのに大いに役立ちました)。http: //www.javadb.com/using-varargs-in-java
PS:私はそれを知っていなかったときに可変引数の使用を恐れていました。しかし、今はそれに慣れています。言われているように、「私たちは既知のものに固執し、未知のものを恐れています」ので、できるだけ多く使用するだけで、あなたも好きになります:)
Varargsは、Javaバージョン1.5で追加された機能です。
なぜこれを使うのですか?
これはどのように機能しますか?
指定された引数で配列を作成し、その配列をメソッドに渡します。
例:
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 );
}
}
出力:
2
合計は12
3
合計は21
私もvarargs関連の恐れがあります:
呼び出し元が明示的な配列を(複数のパラメーターではなく)メソッドに渡すと、その配列への共有参照を受け取ります。
この配列を内部的に格納する必要がある場合は、最初にそれを複製して、呼び出し元が後で変更できないようにすることができます。
Object[] args = new Object[] { 1, 2, 3} ;
varArgMethod(args); // not varArgMethod(1,2,3);
args[2] = "something else"; // this could have unexpected side-effects
これは、状態が後で変化する可能性のある種類のオブジェクトを渡すことと実際には違いはありませんが、通常、配列は(配列ではなく複数の引数を使用した呼び出しの場合)コンパイラによって内部的に作成された安全な新しい配列であるため使用すると、これは確かに予期しない動作です。
ある種のフィルターオブジェクトを取得できるコンストラクターでは、可変引数を頻繁に使用します。たとえば、Hadoopに基づくシステムの大部分は、アイテムのシリアル化と逆シリアル化をJSONに処理するMapperに基づいており、それぞれがコンテンツのアイテムを取得して変更して返すか、nullを返す多数のプロセッサを適用します拒否する。
Var-ArgsのJavaドキュメントでは、var argsの使用法は非常に明確です。
http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html
それが言う使用法について:
「それで、いつvarargsを使うべきですか?クライアントとして、APIがそれらを提供するときはいつでもそれらを利用する必要があります。コアAPIの重要な用途には、リフレクション、メッセージのフォーマット、および新しいprintf機能が含まれます。APIデザイナーとして、それらを使用する必要があります控えめに言っても、メリットが本当に説得力のある場合に限られます。一般的に、varargsメソッドをオーバーロードしてはなりません。そうしないと、プログラマーがどのオーバーロードが呼び出されるかを理解するのが難しくなります。