为什么java支持原始数据类型的函数重载?

通过java中的Autoboxing和unboxing,我了解到java会根据需要将原始数据类型转换为Wrapper Class,反之亦然。 例如,如果函数将Integer作为参数,如果我们将值传递为1那么java编译器会将其转换为new Integer(1) 。 现在下面是我的情况。

 public class JavaTest { public static void Test(Integer integer) { System.out.println("in Integer"); } public static void Test(int integer) { System.out.println("in int"); } public static void main(String[] args) { Test(1); } } 

在这种情况下,java应该抛出编译时exception。 但它成功编译并打印下面的结果

在int

如果我删除了Test(int integer)方法,那么java会给我结果

整数

所以我的问题是为什么java允许这样的函数重载?

Java允许这种重载以实现向后兼容性。

由于在Java 5.0中引入了自动装箱和自动拆箱,因此方法重载解析的第一阶段尝试在不使用自动装箱和自动拆箱的情况下查找匹配方法。

因此,在您的示例中只能找到带有int参数的方法。 删除该方法时,在方法重载决策的第一个阶段中找不到匹配项,第二个阶段使用自动装箱以匹配采用Integer参数的方法。

15.12.2。 编译时间步骤2:确定方法签名

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

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

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

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

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

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