评论由:alexmiller
在第一种情况下,-10000000000000是long类型,编译器明确找到Math.abs(long)。
在第二种情况下,a是Object类型,所有abs签名都被考虑(这在Reflector.invokeMatchingMethod中)。在Java 1.7和1.8中,都找到了"一致的"long和int签名。
在Java 1.7中,首先找到long版本并被处理为匹配项,然后检查int,Compiler.subsumes((link: int), (link: long))返回false,导致保留long方法作为匹配项。
在Java 1.8中,首先找到int版本并被处理为匹配项,然后检查long,Compiler.subsumes((link: long), (link: 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中出现正确结果只能是运气而不是意图。