为何`field(select(...))`与`select(...).asField()`返回类型存在差异?
为什么jOOQ中两段看似等价的代码返回不同类型?
我原本直觉认为下面代码里的变量x和y类型应该一致:
var x = field(select(T.A).from(T)); var y = select(T.A).from(T).asField();
但用IntelliJ将var替换为显式类型后,得到:
Field<String> x = field(select(T.A).from(T)); Field<Object> y = select(T.A).from(T).asField();
想了解这是Java的限制、jOOQ的Bug,还是其他因素?
参考field和asField的方法签名:
public static <T> Field<T> field(Select<? extends Record1<T>> select); public <T> Field<T> asField();
原因分析
这是Java泛型类型推断机制的差异导致的,并非jOOQ的Bug:
- 对于
field(select(T.A).from(T)):Java编译器可以通过field方法的参数类型Select<? extends Record1<T>>,结合select(T.A)返回的Select<Record1<String>>,反向推导出泛型参数T为String,因此x的类型是Field<String>。 - 对于
select(T.A).from(T).asField():asField()是无参数的泛型方法,Java编译器没有足够的上下文信息来自动推断T的具体类型,只能默认使用Object作为泛型参数,所以y的类型是Field<Object>。
解决办法
如果希望y也获得Field<String>类型,可以显式指定泛型参数:
var y = select(T.A).from(T).<String>asField();
内容的提问来源于stack exchange,提问作者Alf
相关产品推荐
相关产品推荐

