评论者: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在这种情况下得到正确的结果。