Java Generic在返回方法强制转换时扩展

时间:2012-11-21 15:56:12

标签: java generics casting

我有一个返回泛型类型列表的方法,方法如下所示。

    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>

2 个答案:

答案 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>的子类中被覆盖。