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 の型に関係なく) を必要とするメソッド (またはコンストラクター) には、varargs を使用してください」。
これにより、これらのメソッドの呼び出しが簡単になります (実行する必要はありませんnew T[]{...}
)。
この規則を拡張してList<T>
、この引数が入力専用である (つまり、リストがメソッドによって変更されない) 場合は、引数を持つメソッドを含めることができます。
f(Object... args)
また、不明確なAPIを使用したプログラミング方法に陥るため、使用を控えます。
例に関しては、私はそれをDesignGridLayoutJComponent
で使用しました。ここでは、1 回の呼び出しで複数の を追加できます。
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
上記のコードでは、add() メソッドは として定義されていadd(JComponent... components)
ます。
最後に、そのようなメソッドの実装では、空の可変引数で呼び出される可能性があるという事実に注意する必要があります! 少なくとも1つの引数を課したい場合は、次のような醜いトリックを使用する必要があります:
void f(T arg1, T... args) {...}
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() へのすべての呼び出しが再び有効になります。
もちろん、可変引数を簡単に避けて、代わりに次のことを行うこともできます。
private void debugPrint(String msg) {
System.out.println(msg);
}
debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
+ serialNo + ", the grade is " + grade);
ただし、この場合、debugPrint() コードをコメント アウトすると、サーバーは debugPrint() を呼び出すたびにすべての変数を連結するという問題を解決しなければなりませんが、結果の文字列は何も処理されません。ただし、varargs を使用する場合、サーバーはそれらを必要としないことに気付く前に、それらを配列に配置するだけで済みます。多くの時間が節約されます。
メソッドで渡される引数の数が不明な場合は、Varargs を使用できます。バックグラウンドで指定されていない長さのパラメーターの配列を作成し、そのようなパラメーターは実行時に配列として扱うことができます。
異なる数のパラメーターを受け入れるようにオーバーロードされたメソッドがある場合、メソッドを異なる回数オーバーロードする代わりに、単純に 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 を使用することを恐れていました。でも今は慣れました。よく言われるように、「私たちは既知のものに執着し、未知のものを恐れる」ので、できる限り使用してください。あなたもそれを好きになるでしょう:)
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
これは、後で状態が変化する可能性のあるオブジェクトを渡すことと実際には違いはありませんが、配列は通常 (配列ではなく複数の引数を使用して呼び出した場合) コンパイラによって内部的に作成された新しいものであるため、安全に実行できます。これは確かに予期しない動作です。
私は、ある種のフィルター オブジェクトを受け取ることができるコンストラクターに対して、varargs を頻繁に使用します。たとえば、Hadoop に基づくシステムの大部分は、JSON へのアイテムのシリアル化と逆シリアル化を処理する Mapper に基づいており、それぞれがコンテンツのアイテムを受け取り、それを変更して返すか、null を返す多数のプロセッサを適用します。拒否する。