我可以在 EJB 方法中抛出 AssertionError 吗?

May I throw an AssertionError in an EJB method?

遵循 Joshua Bloch 的 Effective Java 中使用的样式并同意 this 问题的答案,我过去在 Java SE 环境中使用过 AssertionErrors永远不可能执行的代码路径。

查看 Java EE,EJB 3.1 规范说

If the bean method encounters a system exception or error, it should simply propagate the error from the bean method to the container (i.e., the bean method does not have to catch the exception).

再往下一点,它说在非 ApplicationException 的情况下必须丢弃相关的 EJB 实例。据我所知,如果在后续请求中需要该 EJB 的另一个实例,则容器会从池中获取一个实例或在必要时创建一个新实例,因此应该没有与之相关的问题(当然,如果它是@Singleton EJB).

在会话 bean 方法中使用 AssertionError 来指示编程错误是 appropriate/good 风格吗?或者是否有更合适的 Throwable 子类型?

我真的没觉得扔 AssertionError 有什么不妥。容器应该能够执行回滚,就像处理任何未处理的异常一样。

话虽如此,我自己从不扔 AssertionError。我会抛出 RuntimeException 的子类的几个常见示例可能比 AssertionError 更合适,它们是:

假设我们有一个 enum:

public enum TestEnum {
  TEST1, TEST2;
}

我想捕获默认情况,在此我抛出一个 IllegalArgumentException:

public class TestClass {

  public void doSomethingWithTestEnum(TestEnum testEnum) {
    switch (testEnum) {
    case TEST1:
      // do something here
      break;
    case TEST2:
      // do something here
      break;
    default:
      throw new IllegalArgumentException("Unknown enum type: " + testEnum);
    }
  }

}

另一个例子是参数验证:

public class TestClass {

  private String testString;

  public TestClass(String testString) {
    this.testString = Objects.requireNonNull(testString);
  }

}

此处,如果 testString 为 null,则抛出 NullPointerException

可能有断言更合适的情况,但老实说我从未遇到过。