如何将Class列表作为参数传递?

Fre*_*Ren 3 java exception

我试图有一个handleException方法,它可以采用异常对象和可接受的异常类列表来检查异常是否可以接受并且可以重试.

void handleException(Exception e, String... acceptableExceptionNames)
      throws MyException {

    boolean isRetryable = false;

    for(String acceptableExceptionName: acceptableExceptionNames) {
      try {
        if (Class.forName(acceptableExceptionName).isInstance(e)) {
          isRetryable = true;
          break;
        }
      } catch (ClassNotFoundException e1) {
        continue;
      }
    }

    if (isRetryable) {
      // log retryable
    } else {
      // log error
    }

    throw new MyException(isRetryable, "Failed");
  }
Run Code Online (Sandbox Code Playgroud)

我传入的参数是a String... classNames而不是Class<? extends Exception> classes,因为如果我做这样的事情:

void handleException(
    Exception e,
    Class<? extends Exception>... acceptableExceptions)
      throws MyException {
    for (Class acceptableException : acceptableExceptions) {
        if (e instanceOf acceptableException) {}
    }
}
Run Code Online (Sandbox Code Playgroud)

IDE会抱怨 unknown class acceptableException

谁知道有没有办法通过Class<?>?或者更好的方法来避免使用String classNamesClass.forName()

Mur*_*nik 6

acceptableExceptions不是Class,它是一个Class[].但是,您可以保留原始设计,只需Class直接使用对象,而不是从字符串创建它们:

void handleException
        (Exception e, Class<? extends Exception>... acceptableExceptionNames)
        throws MyException {

    boolean isRetryable = false;

    for(Class<?> acceptableExceptionName: acceptableExceptionNames) {
        if (acceptableExceptionName.isInstance(e)) {
            isRetryable = true;
            break;
        }
    }

    if (isRetryable) {
        // log retryable
    } else {
        // log error
    }

    throw new MyException(isRetryable, "Failed");
}
Run Code Online (Sandbox Code Playgroud)

编辑:
作为旁注,使用Java 8的流可以大大缩短此代码:

void handleException
        (Exception e, Class<? extends Exception>... acceptableExceptionNames)
        throws MyException {

    boolean isRetryable = 
        Arrays.stream(acceptableExceptionNames).anyMatch(x -> x.isInstance(e));

    if (isRetryable) {
        // log retryable
    } else {
        // log error
    }

    throw new MyException(isRetryable, "Failed");
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么要更换`Class <?扩展Exception>`with`Class <?>`?您不再限制类类型. (2认同)