Base
上述代码的输出是“int”。但它应该是“长”因为字节类型参数函数已经存在。但是这里程序正在将字节值提升为int,但情况并非如此。
有人可以澄清这里发生了什么吗?
答案 0 :(得分:10)
JLS 15.12.2是这里要看的规范的相关部分。特别是 - 强调我的:
该过程的其余部分分为三个阶段,以确保与Java SE 5.0之前的Java编程语言版本兼容。阶段是:
第一阶段(§15.12.2.2)执行重载解析而不允许装箱或拆箱转换,或使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第二阶段。
这保证了在Java SE 5.0之前在Java编程语言中有效的任何调用都不会因为引入变量arity方法,隐式装箱和/或拆箱而被认为是不明确的。 但是,变量arity方法(第8.4.1节)的声明可以更改为给定方法方法调用表达式选择的方法,因为变量arity方法被视为一个固定的arity方法第一阶段。例如,在已声明
m(Object...)
的类中声明m(Object)
会导致m(Object)
不再被选择用于某些调用表达式(例如m(null)
),因为m(Object[])
更具体。第二阶段(第15.12.2.3节)执行重载解析,同时允许装箱和拆箱,但仍然排除使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。
这确保了如果通过固定的arity方法调用适用,则永远不会通过变量arity方法调用选择方法。
第三阶段(§15.12.2.4)允许重载与变量arity方法,装箱和拆箱相结合。
在您的情况下,第一阶段找到匹配而不使用变量arity方法调用或装箱,因此这就是结果。如规范中所述,这基本上是为了向后兼容。
答案 1 :(得分:2)
在重载方法的情况下,变量参数方法将始终是编译器选择的最后一个方法。与采用var-arg参数的方法相比,将byte
升级为int
(扩展转换)将更受欢迎。
背后的原因是语言需要向后兼容。较旧的功能将优先于较新的功能。理解JLS关于变量参数的说法的一种简单方法是扩大将击败拳击和拳击将击败var-args。