【问题标题】:Variable argument function ambiguity变量参数函数歧义
【发布时间】:2010-09-27 10:55:54
【问题描述】:
   public static void main(String[] args) {
       System.out.println(fun(2,3,4));
     }
   static int fun(int a,int b,int c)
   {
     return 1;
   }
   static int fun(int ... a)
   {
     return 0;  
   }

输出: 1

问题: 在上述情况下,为什么函数 fun 选择第一个函数而不是第二个函数。由于无法确定用户实际想要调用哪个 fun,选择的依据是什么?

【问题讨论】:

    标签: java variadic-functions overloading


    【解决方案1】:

    基本上对特定呼叫有偏好。除此之外,这意味着可以针对少量参数进行优化,避免在执行时无意义地创建数组。

    JLS 并没有说得很清楚,但它在section 15.12.2.5 中,如果某些条件成立,则讨论固定数量方法比另一种方法更具体的部分 - 在这种情况下它们确实如此。基本上它更具体,因为有更多的调用对可变参数方法有效,就好像有相同数量的参数但参数类型本身更一般。

    【讨论】:

      【解决方案2】:

      当遇到这些歧义时,编译器总是选择精确的方法。在您的场景中,具有三个参数的 func 比一个变量参数更精确,因此被调用。

      编辑:已根据 skeet 的评论进行编辑。

      【讨论】:

      • 决定这一点的不是 JVM——而是编译器。
      【解决方案3】:

      如果你测试这个表达式:

          System.out.println(fun(2,3,4));
          System.out.println(fun(2,3));
          System.out.println(fun(2,3,4,7));
      

      输出是

      1
      0
      0
      

      Java 编译器首先检查其声明与调用的确切参数匹配的方法,否则,它会搜索替代方法匹配。

      【讨论】:

        【解决方案4】:

        此行为允许解析两个重载的变量参数调用:

        addStates(String... states)
        addStates(Enum... states)
        

        调用 addStates() 会产生编译歧义问题。添加第三种方法:

        addStates(){
           addStates(new String[0]);
        }
        

        这允许选择更具体的第三个 addStates() 来解决不确定调用哪个变量类型参数方法的歧义问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-12-31
          • 2021-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多