如何从一个类的多个构造函数调用一个通用的静态实用程序方法,而在整个构造函数之间只有一个调用?

时间:2019-02-14 09:22:40

标签: java

我正在编写一个实用程序,当发生用户定义的异常(MyException)时可以调用该实用程序。我的方法是从MyException类的构造函数调用此实用程序。但是,在所有构造函数中显式调用相同的实用程序方法看起来很多余。有没有一种方法可以从所有构造函数中调用我的方法,而无需在所有这些构造函数中明确声明MyUtil.invoke()?

public class MyException extends Exception {

private static final long serialVersionUID = 1L;

public MyException() {
    super();
}

public MyException(final Throwable e) {
    super(e);
    ExceptionUtil.logExceptionToElasticSearchServer(e.getMessage());
}

public MyException(final String message) {
    super(message);
    ExceptionUtil.logExceptionToElasticSearchServer(message);
}

public MyException(final String message, final Throwable e) {
    super(message, e);
    ExceptionUtil.logExceptionToElasticSearchServer(message);
}

}

2 个答案:

答案 0 :(得分:4)

简单的方法可能是构造函数伸缩,如:

public MyException() {
    this(null, null); 
}

您仅实现带有两个参数的最后一个构造函数,所有其他构造函数都调用该参数!

当然,这里的隐含假设是,最终,您的实用程序方法也会在“相同”调用中组合在一起。到目前为止,您的构造函数都在调用不同的方法。

除此之外,真正的答案是:不要那样做。构造函数创建一个 new 对象。发出日志到某个服务器左右是一点都不的事情!

严重的是,这是一个坏主意:

  • 当您的异常得到extended时会发生什么?您确定始终要记录所有实例,甚至是子类中的实例吗?
  • 该静态调用将使进行正确的单元测试变得困难得多。您将不得不嘲笑该静态实现(使用PowerMock(ito),不好的主意)。
  • 这也使其他测试更加困难。如果在某个时候需要简单地实例化这样的异常对象,而又不会抛出它,该怎么办?是否仍应记录“未抛出”异常?还是您现在需要登录并“注销”它?!

而且非常糟糕:您正在创建异常,因为某些失败。现在假设:您在该日志代码中的某个地方存在一个错误。那只会“随机地”开始。现在发生的事情是:您的产品有时会遇到异常(由X引起),但是在尝试处理该问题时,您遇到了另一个异常。潜在的结果可能是您丢失了有关 X 事件发生的信息。问题是:错误处理应该简单明了。在幕后隐藏来自构造函数的异常记录不是是一个好主意。

例外的想法是: -它们被创建并抛出 -它们被捕获并“处理”。

这种日志记录属于该“处理”部分。 捕获这些异常的组件可以很高兴地调用该静态方法,但不能高兴地调用异常本身。

异常的责任是提供有关失败的信息。 负责部分必要的错误处理!

答案 1 :(得分:1)

您可以创建自己的abstract类,该类extends异常,从其构造函数中调用实用程序方法,并使Implementation类对其进行扩展,例如:

public abstract class BaseException extends Exception {
    public BaseException(Throwable t) {
        super(t);
        ExceptionUtil.logExceptionToElasticSearchServer(t);
    }
    //Other constructors
}

完成后,您的impl类将如下所示:

public class MyException extends BaseException {

    private static final long serialVersionUID = 1L;

    public MyException() {
        super();
    }

    public MyException(final Throwable e) {
        super(e);
    }

    public MyException(final String message) {
        super(message);
    }

    public MyException(final String message, final Throwable e) {
        super(message, e);
    }

}