J2SE1.4まで、Javaプログラムで変数の実際のパラメーターを使用してメソッドを定義することは不可能でした。これは、Javaでは、実際のパラメーターの数と種類(引数)と正式なパラメーターを1つずつ一致させる必要があり、正式なパラメーターの数がメソッドを定義するときに修正する必要があるためです。同じ方法には、過負荷メカニズムを介して異なる数の正式なパラメーターを提供できますが、これはまだ実際のパラメーター量が任意に変更できるようにする目的を達成することはできません。
ただし、いくつかの方法のセマンティクスでは、実際のパラメーターの変動数を受け入れることができる必要があります。たとえば、有名なメインメソッドは、すべてのコマンドラインパラメーターを実際のパラメーターとして受け入れる必要があり、コマンドラインパラメーターの数を事前に決定することはできません。
この問題では、伝統的に、「配列を使用して渡される実際のパラメーターをラップする」という練習は、一般にそれを処理するために使用されます。
1.パラメーターを配列に巻き付けます
「実際のパラメーターを配列でラップする」の練習は、3つのステップに分けることができます。まず、この方法の配列型パラメーターを定義します。次に、呼び出されると、渡されるすべての実際のパラメーターを含む配列を生成します。最後に、この配列を実際のパラメーターとして渡します。
このアプローチは、「メソッドに変数パラメーターを受け入れる」という目的を効果的に実現できますが、呼び出しの際のフォームは十分に単純ではありません。
VarargsメカニズムはJ2SE1.5で提供されているため、複数の実際のパラメーターに一致する形式的パラメーターの直接的な定義が可能になります。したがって、実際のパラメーターの可変数をより簡単に渡すことができます。
Varargsの意味
一般的に言えば、「varargs」は「variablenumber -ofarguments」を意味します。単に「variablearguments」と呼ばれることもありますが、この用語は何が変動するものを示していないため、意味は少し曖昧です。
2。可変リアルパラメーターを使用してメソッドを定義します
3つの連続した「」を追加するだけです。 (つまり、「...」、英語の文の楕円である)「タイプ」と正式なパラメーターの「パラメーター名」との間の間に、不確実な実際のパラメーターと一致させることができます。このような正式なパラメーターを備えた方法は、変数の実際のパラメーターを持つ方法です。
リスト1:変数の実際のパラメーターを備えたメソッド
private static int sumup(int ... values){}最後の正式なパラメーターのみが「不確実な実際のパラメーターと一致できる」と定義できることに注意してください。したがって、メソッドにはそのような正式なパラメーターは1つだけです。さらに、この方法に他の正式なパラメーターがある場合は、それらを前の位置に置きます。
コンパイラは、最後の正式なパラメーターを秘密裏に配列形式のパラメーターに変換し、コンパイルされたクラスファイルにマークを作成して、これが可変実際のパラメーターを持つ方法であることを示します。
リスト2:変数の実際のパラメーターを持つメソッドの秘密形式
private static int sumup(int [] values){}このような変換のため、変換されたメソッドの署名と一致するこのクラスのメソッドを定義することは不可能です。
リスト3:コンピレーションエラーを引き起こす組み合わせ
Private static int sumup(int ... values){} private static int sumup(int [] values){}3.実際のパラメーターの可変数のメソッドを呼び出す
渡される実際のパラメーターが対応する位置に1つずつ記載されている限り、変数数の実際のパラメーターを持つ方法を呼び出すことができます。他の手順は必要ありません。
リスト4:いくつかのパラメーターを渡すことができます
sumUp(1,3,5,7);
間接的に、コンパイラはこの呼び出しプロセスを「実際のパラメーターに包まれた配列」の形式に変換します。
リスト5:密かに表示される配列作成
sumUp(newint[]{1,2,3,4});
さらに、ここで言及されている「不確実なもの」にはゼロも含まれているため、このような呼び出しは合理的です。
リスト6:実際のパラメーターゼロを渡すこともできます
sumUp();
コンパイラによって密かに変換されるこの呼び出し方法の効果は、これに相当します。
リスト7:ゼロの実際の引数は、空の配列に対応しています
sumUp(newint[]{});
この時点で過去はnullではなく渡されていることに注意してください。これにより、どの状況が属するかを検出することなく、統一されたフォームを処理できます。
4.変数数で実際のパラメーターを処理します
変数数の実際のパラメーターを処理する方法は、基本的にアレイの実際のパラメーターを処理する方法と同じです。すべての実際のパラメーターは、正式なパラメーターと同じ名前の配列に保存されます。実際のニーズに応じて、このアレイ、蒸し、または調理の要素を読んだ後、必要なことは何でもできます。
リスト8:受信した引数の処理
private static int sumup(int ... values){int sum = 0; for(int i = 0; i <values.length; i ++){sum+= values [i]; } return sum;}5.変数数のパラメーターを転送します
時には、変数数パラメーターのセットを受け入れた後、別の変数番号メソッドに渡す必要がある場合があります。エンコード中に受信した実際のパラメーターの数はわかりません。「表示すべき場所に1つずつ書く」という慣行は実現不可能です。ただし、これは、変数の実際のパラメーターを持つメソッドを呼び出す別の方法があるため、これが未解決のタスクであることを意味するものではありません。
J2SE1.5コンパイラの目には、可変リアルパラメーターを備えたメソッドは、最後に正式なパラメーターの配列を備えた方法の特別なケースです。したがって、実際のパラメーターのセット全体を事前に配列に渡すように配置し、この配列を最後の実際のパラメーターとして、変数数の実際のパラメーターを備えたメソッドに渡しますが、これはエラーを引き起こしません。この機能を使用すると、転送をスムーズに完了できます。
リスト9:受信した実際のパラメーターを転送します
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、object ... args){system.out.printf(format、args); }}6。それは配列ですか?アレイではありませんか?
舞台裏では、コンパイラは不確実な実際のパラメーターを配列の正式なパラメーターに一致させることができる正式なパラメーターを変換します。また、配列を使用して実際のパラメーターをラップし、実際のパラメーターの数が可変のメソッドに渡すこともできます。ただし、これは、「不確実な実際のパラメーターに一致できる正式なパラメーター」と「配列の正式なパラメーター」に違いがないことを意味するものではありません。
明らかな違いは、最後の正式なパラメーターが、さまざまな数の実際のパラメーターを持つメソッドの形式の配列形式パラメーターであるメソッドを呼び出す場合、「Can beappliedto」コンパイルエラーにのみつながることです。
リスト10:「Can CanbeAppliedto」の編集エラー
private static void testoverloading(int [] i){system.out.println( "a");} public static void main(string [] args){testoverloading(1、2、3); //コンパイルエラー}このため、実際のパラメーターのみをサポートするメソッド(たとえば、J2SE1.5のサードパーティライブラリデザインに残されたもの)のみをサポートするメソッドを呼び出す場合、この簡潔なコールメソッドを直接採用することはできません。
元のクラスを変更できず、呼び出されるメソッドにパラメーターの数の変数バージョンを追加し、この簡潔な呼び出しメソッドを採用する場合は、「導入ForeignMethod」と「introw colocelextion」の再構成方法を使用して目的を近似できます。
7.さまざまな数の引数がジェネリックに遭遇するとき
J2SE1.5に新しい「一般的な」メカニズムが追加されており、特定の条件下でタイプをパラメーター化できます。たとえば、クラスを作成する場合、メソッドの正式なパラメーターのタイプは識別子(tなど)で表すことができます。この識別子が表すタイプについては、このクラスのインスタンスを生成するときに指定されます。このメカニズムを使用して、より完全なコードの再利用とより厳格なコンパイルタイムタイプチェックを提供できます。
ただし、一般的なメカニズムは、さまざまな数の正式なパラメーターでは使用できません。不確実な引数に一致する正式なパラメータータイプが識別子によって表される場合、コンパイラは「genericArraycreation」エラーを与えます。
リスト11:Varargsがジェネリックを満たしているとき
private static void testvarargs(t ... args){//コンピレーションエラー}この現象の理由は、J2SE1.5の一般的なメカニズムの固有の制約です - このタイプのインスタンスは、識別子で表されるタイプでは作成できません。この制約なしでサポートするJavaバージョンが表示される前に、基本的にこの問題に対する良い解決策はありませんでした。
ただし、従来の「アレイ付きのラップ」プラクティスは、この制約の対象ではありません。
リスト12:編集可能な回避策
private static void testvarargs(t [] args){for(int i = 0; i <args.length; i ++){system.out.println(args [i]); }}8。過負荷の選択の問題
Javaは「オーバーロード」メカニズムをサポートしており、同じクラスの多くの異なる方法が正式なパラメーターのリストのみを持つことができます。次に、コンパイラは、呼び出し時に実際のパラメーターに基づいて実行する方法を選択します。
従来の選択は基本的に「特別な人々が好ましい」という原則に基づいています。メソッドの専門性は、スムーズに実行するために満たす必要がある条件の数に依存します。必要な条件が多いほど、特別な条件が増えます。
Varargsメカニズムの導入後、この原則はまだ適用されますが、考慮すべき問題は豊かになります - 従来、過負荷の方法のさまざまなバージョンの中で、形態学的パラメーターと実際のパラメーターがまったく同じであるもののみがさらなる検討のために適格です。ただし、Varargsメカニズムの導入後、両方のバージョンを一致させることができ、他の側面に違いはありません。ただ1つの実際のパラメーターには固定数があり、他の実際のパラメーターには変数数があります。
この場合、使用される決定ルールは、「固定された数の実際のパラメーターを持つバージョンが、可変数の実際のパラメーターを持つバージョンよりも優先される」というものです。
リスト13:実際のパラメーターが固定されているバージョンが推奨されます
コンパイラのビューで、複数の方法が同じ優先順位を持っている場合、どの方法を呼び出すかについて選択できない状態に閉じ込められます。この場合、「メソッド名と呼ばれるリファレンセットISAMBIGUOUS」のコンパイルエラーが生成され、混乱している新しいソースコードの到着を避けるために、いくつかの変更を辛抱強く待ちます。
Varargsメカニズムの導入後、混乱につながる可能性のあるこの状況はもう少し増加しました。たとえば、一致できる2つのバージョンがある場合がありますが、これは他の側面ではまったく同じであり、実際のパラメーターの可変数との両方の競合が発生します。
public class overloadingSamplea {public static void main(string [] args){testoverloading(1); // print out atestoverloading(1、2); // print out out out out out out out out out out out out out out out out out out out out out out out c} j){system.out.println( "b");} private static void testoverloading(int i、int ... more){system.out.println( "c");}}}コンパイラのビューで、複数の方法が同じ優先順位を持っている場合、どの方法を呼び出すかについて選択できない状態に閉じ込められます。この場合、「メソッド名と呼ばれるリファレンセットISAMBIGUOUS」のコンパイルエラーが生成され、混乱している新しいソースコードの到着を避けるために、いくつかの変更を辛抱強く待ちます。
Varargsメカニズムの導入後、混乱につながる可能性のあるこの状況はもう少し増加しました。たとえば、一致できる2つのバージョンがある場合がありますが、これは他の側面ではまったく同じであり、実際のパラメーターの可変数との両方の競合が発生します。
リスト14:何があっても、コンパイラが
public class overloadingSampleb {public static void main(string [] args){testoverloading(1、2、3); //コンピレーションエラー} private static void testoverloading(object ... args){}}さらに、J2SE1.5には「自動ボクシング/自動ユンボックス化」メカニズムがあるため、両方のバージョンが一致し、実際のパラメーターの数が可変であり、他の側面はまったく同じです。 1つの許容可能な実際のパラメーターが基本タイプであるということですが、もう1つの許容可能な実際のパラメーターは、パッケージクラス間の競合です。
リスト15:オートボクシング/自動不動の問題からの新しい問題
public class overloadingSamplec {public static void main(String [] args){/*コンパイルエラー*/テストオーバーロード(1、2);/*またはコンパイル*/テストオーバーロード(新しい整数(1)、新しい整数(2));}プライベート静的ボイドテストオーバーロード(...9。概要
「アレイでラップされた」メソッドと比較して、変数の実際のパラメーターを備えた実際の方法はより単純で、呼び出し時により明確な意味があります。ただし、このメカニズムには独自の制限もあり、完璧なソリューションではありません。
上記は、Javaの可変長さパラメーターコードのすべての詳細な説明です。すべての人に役立つことを願っています。興味のある友達は引き続きこのサイトを参照できます:
Javaの暗黙のパラメーターと表示パラメーターインスタンスの詳細な説明
Javaプログラミングクイックソートと最適化コードの実装詳細な説明
Java暗号化の復号化とデジタル署名完全コードの例
欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!