5

一致しないパラメーターを含むメソッドをオーバーロードする場合、JVMは常に、パラメーターよりも幅が広い最小の引数を持つメソッドを使用します。

私は次の2つの例で上記を確認しました:

拡大:バイトがintに拡大

class ScjpTest{

    static void go(int x){System.out.println("In Int");}
    static void go(long x){System.out.println("In long");}

    public static void main (String[] args){

        byte b = 5;

        go(b);

    }

}

ボクシング:整数にボックス化されたint

class ScjpTest{

    static void go(Integer x){System.out.println("In Int");}
    static void go(Long x){System.out.println("In Long");}

    public static void main (String[] args){

        int b = 5;

        go(b);

    }

}

上記の両方の例は、正しい「InInt」を出力します。次の例に示すように、状況にvar-argsが含まれる場合は、混乱します。

class ScjpTest{

    static void go(int... x){System.out.println("In Int");}
    static void go(long... x){System.out.println("In lInt");}

    public static void main (String[] args){

        byte b = 5;   //or even with:  int b = 5

        go(b);

    }

}

上記の場合、次のエラーが発生します。

ScjpTest.java:14: reference to go is ambiguous, both method go(int...) in ScjpTest and method go(long...) in ScjpTest match
                go(b);
                ^
1 error

前の例と同じルールを適用しないのはなぜですか?つまり、バイトよりも大きい最小値であるため、バイトをintに広げますか?

4

3 に答える 3

5

var-args 構文は、配列を引数として渡すための単なるエイリアスです。

foo(int ... arg)に等しいfoo(int[] arg)

しかし、配列は階層的ではありません。String[]のサブクラスではありませんObject[]。メソッドの引数についても、まったく同じ規則が適用されます。long[]したがって、コンパイラは、 とint[]を渡すときに を受け入れる 2 つのオーバーロードされたメソッドを区別できませんbyte

于 2011-08-14T13:05:52.573 に答える
1

実際にはJava 7で動作します.varargsの例でも「In Int」を返します。以前のバージョンでは欠落していた機能だったと思います。使用しているJavaのバージョンはわかりませんが、Java 6でも機能している可能性があります。

ただし、最初の例でさえ(可変引数なしで)機能することに驚いたと言わざるを得ません。プリミティブな拡大変換については知りませんでした。ちなみに、代わりに Byte、Integer、Long を使用すると、最初と最後の例は失敗します。これらの型の間に階層がないためです (ただし、それらはすべて Number のサブクラスです)。

于 2011-08-14T13:39:25.983 に答える
1

AlexR が指摘したように、var-args は配列のようなものです。プリミティブの配列 ( などはbyte[] short[] int[] long[] float[] double[]、同じクラスに内部的にコンパイルされているようです。そのため、オーバーロードされたメソッドがあいまいです。しかし、次のコードは完全に有効です: これは正常にコンパイルされ (とは異なる型であるため)、出力 を生成し ます。「SCJP の準備をしています。SCJP Sun Certified Programmer for Java 6 Exam 310-065という本を読むことを強くお勧めします。この本のオーバーロードのセクションでは、ボクシングと var-args を組み合わせたすべてのトリックについて説明しています。
static void go(int... x){System.out.println("In Int");}
static void go(Long... x){System.out.println("In lInt");}

int[]Long[]In Int

于 2011-08-14T13:40:58.687 に答える