【问题标题】:Java method dispatch with null argument带有 null 参数的 Java 方法分派
【发布时间】:2010-09-27 11:49:03
【问题描述】:

为什么(显然)是我直接传递null 作为参数,还是传递我分配了 nullObject

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 的第二个答案中的评论。)感谢大家的帮助。

【问题讨论】:

    标签: java null method-dispatch


    【解决方案1】:

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

    我确信foo(testVal) 转到foo(Object) 的原因显而易见。

    foo(null) 转到foo(String) 的原因有点复杂。常量null 的类型为nulltype,它是所有类型的子类型。所以,这个nulltype 扩展了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)");
      }
    
    }
    

    【讨论】:

    • 刚刚对此进行了测试,我很惊讶 (a) 6u11 并没有说它是模棱两可的,并且 (b) null 解析为 String 而不是 Object。每天学习新东西 - 为课程 +1。
    • @Software Monkey:一旦您接受常量 null 是 null 类型并且 null 类型是所有类型的子类型,这很明显。对象
    • Pedantry:该方法是用字符串覆盖对象。重载是方法名称相同但签名变化更大的地方。优秀的答案。谢谢。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      -帕特里克

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 嗯,我清理了我的测试类并将其发布到这里,并意识到除了 foo(String) 和 foo(Object),我还有一个 foo(Runnable) - 我现在明白这是导致 foo( null) 是模棱两可的,因为 String 并不比 Runnable 更具体,反之亦然。感谢 Hemal 提供的宝贵帮助!
        猜你喜欢
        • 2014-04-15
        • 1970-01-01
        • 2013-07-17
        • 2012-10-11
        • 1970-01-01
        • 2013-04-23
        • 1970-01-01
        • 2018-04-21
        • 1970-01-01
        相关资源
        最近更新 更多