我迷失在泛型(Java)中。真实场景涉及JPA和CriteriaBuilder
<Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x, Y y);
但我简化了以下类中的相同案例:
public class GenericsTest {
public class Bean<T> {
};
public <T extends Comparable<T>> T targetMethod(Bean<T> bean, T object) {
return object;
}
@SuppressWarnings("unchecked")
public <T> T castToGeneric(Bean<T> bean, Object object) {
return (T) object;
}
@SuppressWarnings("unchecked")
public <T> void understandGenerics(Bean<T> bean, Object object) {
Bean<Comparable<T>> beanOfComparable = (Bean<Comparable<T>>) bean;
Comparable<T> comparableObject = this.castToGeneric(beanOfComparable, object);
this.targetMethod(beanOfComparable, comparableObject);
}
}
最后一行中的调用targetMethod(beanOfComparable, comparableObject)
生成
类型中的方法
targetMethod(Bean<T>, T)
GenericsTest
不适用于参数(Bean<Comparable<T>>, Comparable<T>)
并且我不明白问题出在哪里,因为T
中的targetMethod
必须是Comparable<T>
,这就是我提供的类型。< / p>
答案 0 :(得分:2)
targetMethod
上的约束导致其失败:
public <T extends Comparable<T>> T targetMethod(Bean<T> bean, T object)
当您传入变量(Bean<Comparable<X>>, Comparable<X>)
时,您暗示通用参数T为Comparable<X>
(我在这里使用X来区分泛型与targetMethod和genericGenerics中的泛型)。
targetMethod
上的约束表示当你的T为Comparable<X>
时,T必须延伸Comparable<Comparable<X>>
。当然,这不会令人满意。
我认为你打算做的事情会更好:
@SuppressWarnings("unchecked")
public <T extends Comparable<T>> void understandGenerics(Bean<T> bean, Object object) {
T comparable = (T) object;
targetMethod(bean, comparable);
}
注意,添加约束条件T必须具有可比性,整个过程要简单得多。一般来说,尽可能地限制未经检查的代码是有效的,而是对类型设置约束。