带 null 参数的 Java 方法调度

发布于 2024-07-10 17:21:31 字数 823 浏览 7 评论 0原文

为什么(显然)无论我直接传递 null 作为参数,还是传递我分配了Object,都会产生影响空?

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)");
}

换句话说,为什么对 foo(...) 的第二次调用(已注释掉)没有分派给 foo(Object)

更新:我使用Java 1.6。 我可以毫无问题地编译 Hemal 的代码,但我的代码仍然无法编译。 我看到的唯一区别是 Hemal 的方法是静态的,而我的方法不是。 但我真的不明白为什么这会有所作为......?

更新2:已解决。 我的类中有另一个方法 foo(Runnable),因此调度程序无法明确选择单个最具体的方法。 (请参阅 Hemal 的第二个答案中的评论。)感谢大家的帮助。

Why does it (apparently) make a difference whether I pass null as an argument directly, or pass an Object that I assigned the value 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)");
}

In other words, why is the (commented-out) second call to foo(...) not dispatched to foo(Object)?

Update: I use Java 1.6. I could compile Hemal's code without problems, but mine still doesn't compile. The only difference I see is that Hemal's methods are static while mine are not. But I really don't see why this should make a difference...?

Update 2: Solved. I had another method foo(Runnable) in my class, so the dispatcher couldn't unambiguously select the single most specific method. (See my comment in Hemal's second answer.) Thanks everyone for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

陌伤浅笑 2024-07-17 17:21:32

有人试过这个例子吗???

在 1.6.0 中,foo(null) 被分派到最具体的适用方法,即 foo(String)...

如果添加新方法,如 foo(Integer),编译器将无法选择最具体的适用方法并显示错误。

-帕特里克

Has anyone tried the example ???

With 1.6.0 foo(null) is dispatched to the most specific method applicable which is foo(String)...

If you add a new method say foo(Integer) the compiler cannot choose the most specific applicable method and shows an error.

-Patrick

恰似旧人归 2024-07-17 17:21:32

很抱歉使用答案来发表评论,但我需要发布不适合评论的代码。

@Yang,我还可以编译并运行以下内容。 您能否发布一个完整的代码,该代码可以用注释行进行编译,这样如果我取消注释该行,它就不会编译?

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)");
  }
}

Sorry to use an answer, for a comment, but I need to post code that won't fit in comment.

@Yang, I am also able to compile and run the following. Can you post a complete code that compiles with one line commented such that if I uncomment that line it won't compile?

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)");
  }
}
遗失的美好 2024-07-17 17:21:31

您使用的是哪个版本的 Java? 在 1.6.0_11 中,代码(粘贴在下面)可以编译并运行。

我确信为什么 foo(testVal) 转到 foo(Object) 是显而易见的。

foo(null) 转到 foo(String) 的原因有点复杂。 常量null 的类型为nulltype,它是所有类型的子类型。 因此,这个 nulltype 扩展了 String,而 String 扩展了 Object

当您调用 foo(null) 时,编译器会查找具有最特定类型的重载方法。 由于 StringObject 更具体,因此它是被调用的方法。

如果您有另一个与 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)");
  }

}

Which version of Java are you using? With 1.6.0_11 the code (pasted below) compiles and runs.

I am sure its obvious why foo(testVal) goes to foo(Object).

The reason why foo(null) goes to foo(String) is a little complex. The constant null is of type nulltype, which is a subtype of all types. So, this nulltype extends String, which extends Object.

When you call foo(null) compiler looks for the overloaded method with most specific type. Since String is more specific then Object that is the method that gets called.

If you had another overload that was as specific as String, say foo(Integer) then you would get a ambiguous overload error.

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)");
  }

}
圈圈圆圆圈圈 2024-07-17 17:21:31

因为第二个使用 null 注释掉的调用对于编译器来说是不明确的。 文字 null 可以是字符串或对象。 而分配的值有明确的类型。 您需要强制转换 null,例如 test.foo((String)null) 以消除歧义。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文