从Java中的自绑定泛型返回时,为什么需要强制转换

时间:2017-09-18 20:52:32

标签: java generics inheritance casting

在这种情况下,我的IDE在return语句中显示编译错误。

public class Base<T extends Base>{
    public T get(){
        return this;
    }
}

当我在代码中添加类型转换时,一切正常,但是我不知道为什么需要进行类型转换。

public class Base<T extends Base>{
    public T get(){
        return (T) this;
    }
}

Java是否用有界类型替换所有有界泛型事件?有人可以解释一下幕后发生了什么以及为什么需要进行类型转换?

修改1。

感谢Lothars和algrid的答案,现在很明显,这个独立案例可能导致ClassCastException。这不安全,因此Base应该是抽象的。

这样做的目的是为Builder类创建一个基类,以便扩展方法返回扩展类的类型。这是方法链接所必需的。在下面的示例中,child.setParamOne(1)的返回类型将是Child,尽管它是在继承层次结构中定义的。

这段代码安全吗?您是否有任何建议或替代方案来解决这个问题?

public abstract class Base<T extends Base>{
    int paramOne;

    public T setParamOne(int param){
        this.paramOne = param;
        return (T) this;
    }
}

public final class Child extends Base<Child> {
    int paramTwo;

    public Child setParamTwo(int param){
        this.paramTwo = param;
        return this;
    }
}

public static void main(String[] args) {
        Child c = new Child()
                .setParamOne(1)
                .setParamTwo(1);
}

4 个答案:

答案 0 :(得分:2)

为什么您认为filtered = [s for s in container if 'meet' in s.lower()] 属于this类型?它的类型为T

尝试运行以下代码,您将获得Base<T>

ClassCastException

答案 1 :(得分:0)

此错误的原因与为此类代码创建的错误相同:

$(document).ready()

只是使用泛型。要摆脱编译器错误,您可以像在代码中那样进行转换:

public void myMethod(InputStream is) {
    ByteArrayInputStream bais = is;
}

但是如果传递的输入流不是public void myMethod(InputStream is) { ByteArrayInputStream bais = (ByteArrayInputStream) is; } 或者是从它派生的类,那么这将在运行时失败。您的代码也会发生同样的情况。除非您只创建ByteArrayInputStream的实例,否则在调用Base<Base>时,强制转换会导致错误。

答案 2 :(得分:0)

在你的例子中:

public class Base<T extends Base>{
    public T get(){
        return this;
    }
}

return语句不正确,因为thisBase<T>的实例,而不是T

如果您的目标是返回实例本身(顺便说一下,我不确定您为什么会这样做),代码应该如下所示:

public class Base<T extends Base>{
    public Base<T> get(){
        return this;
    }
}

如果你的目的是返回参数化类型,那么你可能无法做到这一点。参数化类型本身是 Base类中的实例,但同样只是参数化类型。如果这是您所需要的,您可以使用反射获取参数化类型类。

答案 3 :(得分:0)

转换不安全,因为this(类型Base<T>)可能不是T。我们只知道TBase,但不是相反。

无法在Java中表示“自我类型”。所以你想做的事是不可能的。相反,您可以创建一个强制实现子类的抽象方法,以提供返回T的方法:

public class Base<T> {
    public abstract T get();
}

public final class Child extends Base<Child> {
    public Child get() {
        return this;
    }
}