2013-06-07 15 views
5

Java初心者はここです;私はC#でずっと快適です。それは、次のパズルが私に言った。私は Javaで異なるパラメータの署名を持ついくつかのオーバーロードされたクラスを書いています。しかし、Objectとdoubleを区別することはできないようです。ただし、ObjectとDoubleには問題ありません。誰かが何が起こっているのか説明できますか?Javaがオブジェクトと数値を区別できないのはなぜですか?

public void item(Object a, Object b, String c, String d) {/*Stuff*/} 
public void item(double a, double b, String c, String d) {/*Stuff*/} 

public void UseIt(double a, double b, Double c, Double d) 
{ 
    item(a, b, someString, someOtherString); // Claims it's ambiguous 
} 

これは私の開発システムが馬鹿げているケースですか?

申し訳ありません。それは(私は本当にここに置くことはできません)失敗したもののようである、と私はそれを入力する前にそれをしようとしていないのミスを犯し...

+6

あなたのコードは実際に私のために働く。私はこのクラスをコンパイル: パブリッククラスTest { 公共ボイド項目(ダブル、ダブルB、列C、列D){/ *スタッフ* /} 公共ボイド項目(オブジェクトB、列C、文字列オブジェクトd){/ * Stuff * /} public void UseIt(double a、double b、Double c、Double d){ アイテム(a、b、 ""、 ""); //曖昧であると主張します } } –

+0

文字列引数に2つのdoubleを渡しています。 –

+0

引数b、c、dはちょうど赤いニシンです。 –

答えて

4

これはあなたのIDEので(誤解を招く、この場合)オートボクシングが起こる可能性がある。例えば

あなたがList<Integer>を作成した場合、あなたはそれにintを追加することができます。Integerintからオートボクシングがあります。 Unxobingはその逆です:Integerint。 boxingとunboxingの両方は数値プリミティブ型にのみ適用されることに注意してください(の配列ではなく)。

doubleのメソッドが最終的に選択されることは間違いありませんが(より具体的であるため)、IDEでは可能性のあるあいまいさが存在するとみなします。

このサンプルコード:

public final class Test 
{ 
    public static void item(Object a, Object b, String c, String d) 
    { 
     System.out.println("Object"); 
    } 

    public static void item(double a, double b, String c, String d) 
    { 
     System.out.println("double"); 
    } 

    public static void unbox(final double d) 
    { 
     System.out.println("Unboxed!"); 
    } 

    public static void useIt(double a, double b, Double c, Double d) 
    { 
     // primitives 
     item(a, b, "", ""); 
     // cast to corresponding classes 
     item((Double) a, (Double) b, "", ""); 
     // objects 
     item(c, d, "", ""); 
     // unboxed by the "unbox" method which takes a "double" as an argument 
     unbox(new Double(2.0)); 
    } 

    public static void main(final String... args) 
    { 
     // Autoboxing of the third and fourth argument 
     useIt(1.0, 1.0, 1.0, 1.0); 
    } 
} 

出力:

double 
Object 
Object 
Unboxed! 

注しかし、あなたが呼び出すことができない。

useIt((Double) a, b, c, d); // No autoboxing of "b" 
+4

はい、jvmは過負荷のためにボックスにしてはいけません。 someStringとsomeOtherStringを " –

+1

@ TrustNoOne"に置き換えた場合、彼が正しく投稿したコードは私のためにコンパイルされます。 – fge

+0

私はdownvotesがどこから来たのか、理由を知りたいのですが... – fge

-2

をあなたは4と同じ名前です2つのメソッドを持っているので、コンパイラがどのメソッドを参照しているのかわからない可能性があります。あなたの電話には、あなたが電話したい電話の明確な定義はありません。アイテムメソッドの1つの名前を変更するか、より具体的にパラメータを定義する必要があります。

+0

メソッド自体のオーバーロードは、コンパイラでうまくいきます。これは動作しないオーバーロードされたメソッドのあいまいな呼び出しです。 –

+0

...追加するのを忘れました:しかし、これはあいまいではなく、コンパイルします。 –

9

このクラスは、(ちょうどTest.javaに入れて、確認するためにテストされ、コマンドラインからコンパイル)

public class Test { 
    public void item(double a, double b, String c, String d) {/*Stuff*/} 
    public void item(Object a, Object b, String c, String d) {/*Stuff*/} 
    public void UseIt(double a, double b, Double c, Double d) { 
     item(a, b, "", ""); // Claims it's ambiguous 
    } 
} 

あなたの問題は、あなたが2倍を渡しているという事実に関連している可能性がうまくコンパイル(cとd)を2つの文字列の代わりに3番目と4番目の引数として使用します。

+7

これは唯一の正解です。これは皮肉なことです - 「あなたの問題は間違っています」 –

+1

値型とボックス型の間のオーバーロードがうまくいかないとは思えませんでした...私はちょうど答える前にテストしなければなりませんでした:Dそれも私が低所得者を持っている理由です:私はランダムに、スコアを –

+0

OTOHにするだけで、両方のメソッドを 'Object'で始めるように変更すると、動作しません。 –

関連する問題