Java原始拓宽访谈

时间:2016-01-12 19:29:42

标签: java

你能解释一下为什么结果是" int"?我希望它能够长久地#34;如果变量是一个字节。

public class Test{
      public static void printValue(int i, int j, int k){
            System.out.println("int");
      }

      public static void printValue(byte...b){
            System.out.println("long");
      }

      public static void main(String... args){
            byte b = 9;
            printValue(b,b,b);
      }
}

2 个答案:

答案 0 :(得分:12)

Java编译器必须在两种匹配方法之间进行选择。它总会选择一种不使用变量arity(varargs)的方法而不是使用它的方法。它宁愿将int的所有3个参数与第一个printValue相匹配,而不是使用varargs。

Section 15.12.2 of the JLS州:

  

该过程的其余部分分为三个阶段,以确保与Java SE 5.0之前的Java编程语言版本兼容。阶段是:

     
      
  1. 第一阶段(§15.12.2.2)执行重载解析而不允许装箱或拆箱转换,或使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第二阶段。
  2.         

    这保证了在Java SE 5.0之前在Java编程语言中有效的任何调用都不会因为引入变量arity方法,隐式装箱和/或取消装箱而被认为是不明确的。但是,变量arity方法(第8.4.1节)的声明可以更改为给定方法方法调用表达式选择的方法,因为变量arity方法在第一阶段被视为固定arity方法。例如,在已声明m(Object)的类中声明m(Object ...)会导致不再为某些调用表达式(例如m(null))选择m(Object),因为m(Object [] )更具体。

         
        
    1. 第二阶段(§15.12.2.3)执行重载解析,同时允许装箱和拆箱,但仍然排除使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。
    2.         

      这确保了如果通过固定的arity方法调用适用,则永远不会通过变量arity方法调用选择方法。

           
          
      1. 第三阶段(§15.12.2.4)允许重载与变量arity方法,装箱和拆箱相结合。
      2.   

(大胆强调我的)

在第一阶段找到匹配方法(第一次重载),因此编译器甚至不考虑第三阶段 - 允许变量arity方法 - 因此打印int

选择第二个重载(反直觉打印long)的一种方法是显式创建一个数组,以便第一个重载不匹配。

printValue(new byte[]{b,b,b});

答案 1 :(得分:-1)

结果是' int'因为在运行main函数时,你没有使用一个参数printValue,而是使用3个参数。所以编译器假定你正在引用第一个有3个参数的printValue。由于你没有在函数内部使用这些参数,所以在没有任何运行时错误的情况下。另一方面,我会说以这种方式找到变量的类型并不是一个好习惯。最好的方法是使用“if else'声明。您可以参考这篇文章,了解如何在java中找到类型的信息:How do you know a variable type in java?