现在有一件我没想到的事情。
Linda在使用新的JPA 2.0类型安全的criteria API编写的代码时遇到了一些问题,经过调查这个问题后,我真心认为这个应该能编译通过。
QueryBuilder接口定义了以下方法在这种情况下,编译器会抛出一个错误
<Y extends Comparable<Y>> Predicate lessThan(Expression<? extends Y> x, Expression<? extends Y> y);
为什么地狱里?用
Expression<java.sql.Date> x = ....; Expression<java.sql.Date> y = ....; q.where( qb.lessThan(x, y) );
java.util.Date替换Y,所有的界限都满足了java.sql.Date
- 是Comparable<java.util.Date>替换
- 替换Comparable<java.util.Date>的子类型
但显然编译器拒绝考虑,所有的界限都满足了当确定候选者时,所有的界限都满足了:它似乎只从查看参数界限来决定,所有的界限都满足了必须是,它没有实现Comparable<java.sql.Date>。对我来说,这完全是错误的,而且不是直观的。为什么不停在上类型层次结构中查找直到找到匹配项呢?
因此,有两个解决方案。第一个是明确地告诉编译器它自己应该能够解决的事情
q.where( qb.<java.util.Date>lessThan(x, y) );
但更好的解决方案是将API重新声明如下
<Y extends Comparable<? super Y>> Predicate lessThan(Expression<? extends Y> x, Expression<? extends Y> y);
更新:要了解这件事有多疯狂,请考虑以下内容确实可以编译
Expression<java.sql.Date> x = ....; Expression<java.sql.Time> y = ....; q.where( qb.lessThan(x, y) );