有没有办法在Java中说“方法返回这个”?

时间:2009-07-07 08:25:50

标签: java generics

有没有办法说“此方法使用Generics返回this”?

当然,我想在子类中覆盖此方法,因此声明应该与@Override一起使用。

以下是一个例子:

class Base {
    public Base copyTo (Base dest) {
        ... copy all fields to dest ...
        return this;
    }
}
class X extends Base {
    @Override
    public X copyTo (X dest) {
        super.copyTo (dest);
        ... copy all fields to dest ...
        return this;
    }
}

public <T extends Base> T copyTo (Base dest)根本不起作用:我得到“类型不匹配:无法从Base转换为T”。如果我用强制转换强制它,则覆盖失败。

3 个答案:

答案 0 :(得分:5)

你可以做一些非常聪明的事情(类似于他们在Scala中使用2.8 collection framework所做的事情)。声明一些应该返回“本身”的接口方法(注意: This是一个类型参数,而不是关键字!)

public interface Addable<T, This extends Addable<T, This>> {
   public This add(T t);
}

现在声明一个间接级别 - 一个“模板”类

public interface ListTemplate<A, This extends ListTemplate<A, This>> 
    extends Addable<A, This>{
}

public interface List<A> extends ListTemplate<A, List<A>> {
}

然后List的实现必须从List方法返回add(我会让你填写impl详细信息)

public class ListImpl<A> implements List<A> {

    public List<A> add(A a) {
        return ...
    }
}

同样,您可以声明SetTemplateSet来扩展Addable界面 - add方法会返回Set。很酷,嗯?

答案 1 :(得分:4)

不,没有办法表达这一点。只需声明方法以返回类的类型。 Java具有协变返回类型,因此您可以覆盖方法以返回更具体的类型。

如果您想为此设置一些标记,您可以随时引入自己的注释 - 但不要指望任何其他工具可以特别注意它。

编辑:oxbow_lakes的答案确实提供了一些在大多数情况下都会起作用的东西,但我相信有些方法可以愚弄它,这样你实际上就可以处理不同的类型了。 (无论如何,从实验的记忆中。)请注意,这与Java枚举的工作方式类似。

答案 2 :(得分:0)

使用协变类型应该简单如下:

abstract class Foo<T> {

    Foo<T> get() {
        return this.getClass().cast(this);
    }
}

class Bar extends Foo {

    @Override
    Bar get() {
        return (Bar) super.get();
    }
}