当前位置: 首页 > 知识库问答 >
问题:

具有任意异常抛出的模板方法模式

朱啸
2023-03-14

假设我有一个抽象类Base,它有一个具体的方法执行和三个抽象方法stepOnestepTwostepThree...

public abstract class Base {
    protected abstract void stepOne();
    protected abstract void stepTwo();
    protected abstract void stepThree();

    public final void execute() {
        //do stuff
        stepOne();
        //do stuff
        stepTwo();
        //do stuff
        stepThree();
        //do stuff
    }
}

...并且被一个具体的类Sub1

public class Sub1 extends Base {
    protected void stepOne() {
        //...
    }

    protected void stepTwo() {
        //...
    }

    protected void stepThree() {
        //...
    }
}

现在,假设我有第二个子类Sub2,它可以在stepOnestepotwo中抛出一个选中的异常

public class Sub2 extends Base {
    protected void stepOne() throws Exception1 {
        //...
    }

    protected void stepTwo() throws Exception2 {
        //...
    }

    protected void stepThree() {
        //...
    }
}

我想使用以下这些类:

Sub1 s1 = new Sub1();
try {
    s1.execute();
} catch (Exception1 e1) {
    //handle e1
} catch (Exception2 e2) {
    //handle e2
}

Sub2 s2 = new Sub2();
s2.execute();

显然,这不起作用,因为Base中的方法没有声明任何异常。

如何在实现类中抛出任意异常?有没有一种方法不需要使用抛出异常声明执行并且总是必须使用try-catch来实现它?我还想避免将执行中的通用逻辑复制到它的子类中。这里最好的解决方案是什么?对此有更好的设计模式吗?

共有1个答案

司英彦
2023-03-14

下面是通过使Base类方法抛出泛型异常来解决此问题的方法:

public abstract class Base<E1 extends Exception, E2 extends Exception, E3 extends Exception> {
    protected abstract void stepOne() throws E1;
    protected abstract void stepTwo() throws E2;
    protected abstract void stepThree() throws E3;

    public final void execute() throws E1, E2, E3 {
        //do stuff
        stepOne();
        //do stuff
        stepTwo();
        //do stuff
        stepThree();
        //do stuff
    }
}

通过扩展Base,可以创建一个不抛出任何已检查异常的子类

public class Sub1 extends Base<RuntimeException, RuntimeException, RuntimeException> {
    protected void stepOne() {
        //...
    }

    protected void stepTwo() {
        //...
    }

    protected void stepThree() {
        //...
    }
}

下面是您如何创建一个可以在某些步骤中抛出检查异常的子类:

public class Sub2 extends Base<Exception1, Exception2, RuntimeException> {
    protected void stepOne() throws Exception1 {
        //...
    }

    protected void stepTwo() throws Exception2 {
        //...
    }

    protected void stepThree() {
        //...
    }
}

您可以按如下方式使用这些类:

Sub2 s2 = new Sub2();
try {
    s2.execute();
} catch (Exception1 e1) {
    //handle e1
} catch (Exception2 e2) {
    //handle e2
}

Sub1 s1 = new Sub1();
s1.execute();

 类似资料:
  • 编辑: 感谢所有的回复。我找到了解决办法。我试图模拟一个方法findById,它不是直接在User.class中,而是在用户扩展的genericModel.class中。现在一切都很完美。

  • 抛出异常有什么意义?例如,我偶然发现: 但是当你不扔零点的时候,你也会得到一个零点?我经常看到这个,我想知道这是否是一个学习的好习惯?

  • 问题内容: 我正在尝试嘲笑课堂。当我运行以下代码时,Mockito会引发异常: 堆栈跟踪是无限重复的以下几行: 我在这里做错了什么? 问题答案: PS!您还可以模拟对getSecurityManager()方法的静态方法调用。 模拟静态方法请参见maunal,网址为http://code.google.com/p/powermock/wiki/MockitoUsage 在类级别添加@Prepare

  • 上一节展示了如何为ListOfNumbers类中的writeList方法编写异常处理程序。 有时,它适合代码捕获可能发生在其中的异常。 但在其他情况下,最好让一个方法进一步推给上层来调用堆栈处理异常。 例如,如果您将ListOfNumbers类提供为类包的一部分,则可能无法预期包的所有用户的需求。 在这种情况下,最好不要捕获异常,并允许一个方法进一步推给上层来调用堆栈来处理它。 如果writeLi

  • 我有一门课看起来像这样: 我想使用Mockito和Powermock为此编写一个单元测试。我知道我可以这样模仿私有方法: 但是我如何告诉它抛出异常呢?我知道会是这样的: 那里有什么? 请注意,异常是一个私有内部类,因此我不能只执行,因为从单元测试中无法访问。

  • 我正在尝试创建一个模板函子,它将使用任意数量的参数作为参数对象和成员函数。我不知道如何用模板正确地编写代码。 如果我使对象::方法没有参数-代码编译。但是有参数-没有。 严重性代码描述项目文件行抑制状态错误C2664'int Builder::运算符()(T