8

我正在尝试使用辅助方法编写一些自定义异常来设置变量,如下所示:

public class KeyException extends RuntimeException {
    protected String Id;

    protected KeyException(String message) {
        super(message);
    }

    protected KeyException(String message, Throwable cause) {
        super(message, cause);
    }

    public String getId() {
        return keyId;
    }

    public KeyException withId(final String Id) {
        this.Id = Id;
        return this;
    }
}

但是,在我的派生类中,我不能使用“withId”方法,因为它只返回基类 - 是否有返回“this”指针而不必重写每个派生类中的方法?

4

6 回答 6

9

你可以这样做:

public <T extends KeyException> T withId(final String Id) {
    this.Id = Id;
    return (T)this;
}

然后在您的派生类中,您只需将其类型作为类型参数传递。

然而,可能存在设计疏忽。除了构建器模式,我很少看到 setter 返回对对象本身的引用。如果您能提供更多背景信息,我们将能够为您提供更多帮助。

于 2013-08-13T08:37:44.520 回答
9

无论如何都可以返回“this”指针而不必覆盖每个派生类中的方法?

是的,请看下面的选项 1。

您可以在这里执行以下几种方法:

  1. 将结果转换为派生类

  2. 在子类中覆盖它

  3. 将返回类型更改为 void。由于您正在调用对象的方法,因此您已经有一个指向它的指针。

于 2013-08-13T08:33:04.727 回答
5

使用以下构造的泛型是可能的:

public class ParentType<T extends ParentType<T>> {
    public T withId(String someId) {
        /* Insert other code here */
        return (T) this;
    }
}

public class BranchType<T extends BranchType<T>> extends ParentType<T> {}

public final class LeafTypeA extends BranchType<LeafTypeA> {}

public final class LeafTypeB extends ParentType<LeafTypeB> {}

其中BranchType是有子类的类,LeafTypeA、LeafTypeB是没有子类的类。

这比其他泛型解决方案略有改进,因为它可以防止:

public class LeafTypeA extends BranchType<LeafTypeB> {}

由于这不满足类型参数的约束。

于 2016-10-06T13:48:39.327 回答
1

有一种方法可以使用泛型解决返回子类问题:

// base class

public class Base<T extends Base> {

  private T myself;

  public Base(T myself, Class<T> cls) {
    this.myself = myself;
  }

  public T withSomething() {
    return myself;
  }
}

// subclass

public class SomeSubCls extends Base<SomeSubCls> {

  public SomeSubCls() {
    super(this, SomeSubCls.class);
  }
}

使用此模式new SomeSubCls().withSomething()会将对象作为子类的实例返回,而不是父类。

例如,由fest 断言使用,检查这个

于 2013-08-13T08:41:18.520 回答
1

如果您有派生类,例如

public class AnotherException extends KeyException {
     ...
}

....然后您可以使用withId....简单地分配它

AnotherException a = new AnotherException ("A");
AnotherException b = (AnotherException) a.withId("ID");

...因为它基本上是同一个对象。你只需要投射它。

于 2013-08-13T08:43:49.673 回答
-2

不幸的是没有。如果你能做到这一点就好了

public this withId(final String Id) { // doesn't work
    this.Id = Id;
    return this;
}

要不就

public this withId(final String Id) { // doesn't work either
    this.Id = Id;
}

或者它会知道“无效”方法是隐式链接的(我相信一个正式的提议建议)

于 2013-08-13T08:31:57.447 回答