评论者: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而出现的运气,而不是目的。