13

null引数として直接渡すか、Objectを割り当てたを渡すかによって、(明らかに)違いが生じるのはなぜですか? null

Object testVal = null;
test.foo(testVal);    // dispatched to foo(Object)
// test.foo(null);    // compilation problem -> "The method foo(String) is ambiguous"   

public void foo(String arg) { // More-specific
    System.out.println("foo(String)");
}

public void foo(Object arg) { // Generic
    System.out.println("foo(Object)");
}

つまり、(コメントアウトされた) への 2 番目の呼び出しが にfoo(...)ディスパッチされないのはなぜfoo(Object)ですか?

更新: Java 1.6 を使用しています。Hemal のコードは問題なくコンパイルできましたが、私のコードはまだコンパイルできません。私が見る唯一の違いは、Hemal のメソッドは静的であるのに対し、私のメソッドはそうではないということです。しかし、なぜこれが違いを生む必要があるのか​​ 本当にわかりません...?

更新 2:解決済み。クラスに別のメソッド foo(Runnable) があったため、ディスパッチャは最も具体的なメソッドを 1 つだけ選択することができませんでした。(Hemal の 2 番目の回答の私のコメントを参照してください。) ご協力いただきありがとうございます。

4

4 に答える 4

24

どのバージョンの Java を使用していますか? 1.6.0_11 では、コード (以下に貼り付け) がコンパイルおよび実行されます。

なぜfoo(testVal)行くのかは明らかだと思いますfoo(Object)

foo(null)に行く理由foo(String)は少し複雑です。定数nullの型nulltypeは、すべての型のサブタイプです。したがって、これは をnulltype拡張Stringし、これは を拡張しObjectます。

コンパイラを呼び出すfoo(null)と、最も具体的な型を持つオーバーロードされたメソッドが検索されます。Stringはより具体的であるためObject、それが呼び出されるメソッドです。

String と同じくらい具体的な別のオーバーロードがある場合foo(Integer)、あいまいなオーバーロード エラーが発生するとします。

class NullType {

  public static final void main(final String[] args) {
    foo();
  }

  static void foo()
  {
    Object testVal = null;
    foo(testVal);    // dispatched to foo(Object)
    foo(null);    // compilation problem -> "The method foo(String) is ambiguous"   
  }

  public static void foo(String arg) { // More-specific
    System.out.println("foo(String)");
  }

  public static void foo(Object arg) { // Generic
    System.out.println("foo(Object)");
  }

}
于 2008-12-18T08:45:18.270 に答える
2

Because the second commented out invocation with null is ambiguous to the compiler. The literal null could be a string or an object. Whereas the assigned value has a definite type. You need to cast the null, e.g. test.foo((String)null) to remove the ambiguity.

于 2008-12-18T08:35:17.680 に答える
1

コメントに回答を使用して申し訳ありませんが、コメントに収まらないコードを投稿する必要があります。

@Yang、以下をコンパイルして実行することもできます。その行のコメントを外すとコンパイルされないように、1行をコメントしてコンパイルする完全なコードを投稿できますか?

class NullType {

  public static final void main(final String[] args) {
    foo();
    new Test().bar(new Test());
  }

  static void foo()
  {
    Object testVal = null;
    foo(testVal);    // dispatched to foo(Object)
    // foo(null);    // compilation problem -> "The method foo(String) is ambiguous"   
  }

  public static void foo(String arg) { // More-specific
    System.out.println("foo(String)");
  }

  public static void foo(Integer arg) { // More-specific
    System.out.println("foo(Integer)");
  }

  public static void foo(Object arg) { // Generic
    System.out.println("foo(Object)");
  }


}


class Test
{
  void bar(Test test)
  {
    Object testVal = null;
    test.foo(testVal);    // dispatched to foo(Object)
    test.foo(null);    // compilation problem -> "The method foo(String) is ambiguous"   
  }

  public void foo(String arg) { // More-specific
    System.out.println("foo(String)");
  }

  public void foo(Object arg) { // Generic
    System.out.println("foo(Object)");
  }
}
于 2008-12-18T10:22:49.540 に答える
1

誰かが例を試しましたか???

1.6.0 では、foo(null) は最も具体的な適用可能なメソッド foo(String) にディスパッチされます...

foo(Integer) などの新しいメソッドを追加すると、コンパイラは最も具体的な適用可能なメソッドを選択できず、エラーが表示されます。

-パトリック

于 2008-12-18T08:46:49.857 に答える