我有一个返回泛型类型列表的方法,方法如下所示。
protected <T extends SQLDataBean> List<T> getJavaListFromOracleArray(Array array) throws SQLException
然后我有一个名为ReplacementBean的对象,它扩展了SQLDataBean。
在另一个课程中,我有一个List<ReplacementBean>
,其中一套方法考虑了List<ReplacementBean>
我发现了什么,我不知道为什么我不能在集合中调用上面列出的方法。这意味着这会产生编译时错误:
setReplacements(this.getJavaListFromOracleArray(in.readArray()));
但是以下编译并正常工作。
List<ReplacementsBean> temp = this.getJavaListFromOracleArray(in.readArray());
setReplacements(temp);
我还尝试在set方法中进行如下转换,但它也有编译时错误。
setReplacements((List<ReplacementsBean>)this.getJavaListFromOracleArray(in.readArray()));
有没有办法在调用set方法之前不必进行设置临时局部变量的两行过程?虽然它确实有效,但不必这样做会很好。
调用以下内容:
setReplacements(this.getJavaListFromOracleArray(in.readArray()));
导致错误setReplacements(List<ReplacementsBean>) is not applicable for the arguments List<SQLDataBean>
setReplacements代码如下:
public void setReplacements(List<ReplacementsBean> replacements)
{
this.replacements = replacements;
}
如果我试试这个:
setReplacements((List<ReplacementsBean>)this.getJavaListFromOracleArray(in.readArray()));
我收到错误无法从List<SQLDataBean>
投射到List<ReplacementsBean>
。
答案 0 :(得分:2)
这是编译器类型推断不如您所希望的那样好的情况之一。以下内容应该有效,您可以明确指定泛型方法类型参数:
setReplacements(this.<ReplacementsBean>getJavaListFromOracleArray(in.readArray()));
在临时变量案例中
List<ReplacementsBean> temp = this.getJavaListFromOracleArray(in.readArray());
setReplacements(temp);
编译器被迫将<T>
实例化为<ReplacementsBean>
以使分配工作。
答案 1 :(得分:0)
问题是编译器内部完成了以下操作:
List<X> temp = getJavaListFromOracleArray(in.readArray());
setReplacements(temp);
其中X必须是ReplacementsBean或其子代。这是开放式的。在许多更正式的类型语言中,X被解析,在java中没有。因此需要:
setReplacements(<ReplacementsBean>getJavaListFromOracleArray(in.readArray()));
然而,这种“缺陷”也是一种明确的症状:可能getJavaListFromOracleArray
做了不安全的泛型。
还要注意,函数setReplacements
可能会在参数为List<ReplacementsBeanChild>
的子类中被覆盖。