评论由:alexmiller
在第一种情况下,-10000000000000是一个long,编译器明确地找到Math.abs(long)。
在第二种情况下,a是一个对象,并且所有abs签名都被考虑(这是在Reflector.invokeMatchingMethod中)。在Java 1.7和1.8中,都找到了"一致的"long和int签名。
在Java 1.7中,先找到了long版本,并被视为匹配,然后检查int,Compiler.subsumes((链接: int),(链接: long))返回false,导致long方法被保留为匹配。
在Java 1.8中,先找到int版本,并被视为匹配,然后检查long,Compiler.subsumes((链接: long),(链接: int))返回false,导致int方法被保留为匹配。
这两个在两个JDK上都返回false
(Compiler/subsumes (into-array [Long/TYPE]) (into-array [Integer/TYPE])) (Compiler/subsumes (into-array [Integer/TYPE]) (into-array [Long/TYPE]))
所以真正的区别只是考虑的顺序,这是特定于JDK的。
可以考虑以某种规范方式对考虑的签名进行排序,以使这种行为保持一致,或者也许可以以某种方式表达对两个签名之间的偏好。
无论如何,通过提示或转型消除这里的反射可以解决问题——我认为这应该被视为运气而非意图,因为在Java 7中,这种情况得到了正确的结果。