我正在尝试调试我的一段代码,其中地图中的{Integer
)值有时会出乎意料地高。
当我这样做时
Collection<Integer> vals = newState.values();
int max = Collections.max(vals);
return newState; // breakpoint here
我可以在return语句的行处设置一个条件断点,条件涉及max,例如max > 10
。当我省略中间行并将断点条件设置为Collections.max(vals) > 10
时,我在调试模式下得到运行时异常。
“原因:类型没有实现选择器最大值和签名(Ljava / util / Collection;)Ljava / lang / Comparable;”
我可以通过上面的代码片段得到我想要的东西,但我仍然想知道这里发生了什么。猜测可能是Collections方法未能意识到Integer确实具有可比性,我尝试了Collections.<Integer>max(v)
和一些(语法错误)变体,但没有成功。
答案 0 :(得分:5)
Collections.max()
签名中有一个有趣的技巧:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
正如您所看到的,extends Object
在这里看起来多余。诀窍是在类型擦除期间T
变成了它的第一个通用边界(即Object
),因此这个方法的实际擦除签名如下所示:
public static Object max(Collection coll)
这是为了保留与此方法的预通用版本的二进制兼容性:针对预通用版本编译的代码期望返回类型为Object
,并且使用此技巧新版本满足其期望。
但是,正如您所看到的,调试器错误地认为T
的时代使用是Comparable
。也许这是调试器中的一个错误。
答案 1 :(得分:0)
大多数情况当您使用类引用前缀
在同一范围内调用静态方法时,会发生这种情况实施例
public final class SomeUtilClass{
public static boolean utilMethod1() {
//
}
public static boolean utilMethod2() {
if(SomeUtilClass.utilMethod1()) {
//
}
}
}
在上面的例子中,在utilMethod2中我们使用了utilMethod1来修改类名(即SomeUtilClass.utilMethod1())这是不必要的,因为两者都在同一范围内,它就像调用本地私有方法一样,
在这种情况下,prifix SomeUtilClass。“不需要,如果我们在if条件中移除”SomeUtilClass。“prfix它将会工作得很好,它会在调试时引起这类问题。因为utilMethod2不需要任何类引用调用utilMethod1