3

次のようなコードがあるとします

public class HelloWorld {

    public static String method1(String[] array){return ""+array.length;}
    public static String method2(String... array){return ""+array.length;}


    public static void main(String args[]) {
        System.out.println(method1(new String[]{"test"})); //allowed
        //System.out.println(method1("test")); Not allowed
        System.out.println(method2(new String[]{"test"}));  //allowed
        System.out.println(method2("test")); //allowed
    }
}

私がする時javap HelloWorld

C:\Users\athakur\JavaProjectWorkspace\HelloWorld\bin\test>javap HelloWorld
Compiled from "HelloWorld.java"
public class test.HelloWorld extends java.lang.Object{
    public test.HelloWorld();
    public static java.lang.String method1(java.lang.String[]);
    public static java.lang.String method2(java.lang.String[]);
    public static void main(java.lang.String[]);
}

したがって、クラスファイル method1 と method2 に従って、同じ配列引数を取ります。では、なぜ彼らが取ることができる入力に違いがあるのでしょうか?

method1 のように単純な文字列入力を受け取ることはできませんが、var arg は可変文字列入力と配列を受け取ることができますか?

4

2 に答える 2

7

したがって、クラスファイル method1 と method2 に従って、同じ配列引数を取ります。

method2はい。ただし、パラメーターが varargs パラメーターであることを示すために、クラス ファイル内に追加のメタデータがあります。これは実際には、パラメーターに関する余分なデータにすぎません。それだけです。

を使用して反射で検出できますParameter.isVarArgs

それが意味するのは、コンパイラが次のような呼び出しを喜んで受け入れるということだけです。

method2("test")

暗黙的にそれをに変換します

method2(new String[] { "test" })

常にその動作が必要なわけではないため、varargs 構文を使用してパラメーターで明示的に指定する必要があります。

javap2 つのメソッド宣言の違いが表示されない場合は、少し古いバージョンの も使用していると思われます。私のバージョン(Java 8)では、次のようになります。

public static java.lang.String method1(java.lang.String[]);
public static java.lang.String method2(java.lang.String...);
于 2014-06-08T14:35:11.643 に答える
2

唯一の違いは、引数を 1 つだけ渡すことができる配列引数とは対照的に、可変数の引数を持つ可能性があるメソッドのシグネチャです。とにかく、配列を vararg としてメソッドに渡すことは受け入れられ、内部で使用されます。一方、vararg 引数は配列に変換され、そこで使用されます。

両方のメソッドに引数として配列を渡すと機能します。あなたの質問に答えるために、配列を使用しないでください

System.out.println(method2("test")); //allowed
System.out.println(method2("test","test2")); //allowed

お気づきのように、これは vararg 引数を使用する場合にのみ機能します。

于 2014-06-08T14:44:13.650 に答える