0

假设我有几个类:

Class ExceptionA{
    public ExceptionA(ExceptionA.ErrorCode errorCode){}
    setters...
    getters...
    public static enum ErrorCode{
        EC_ABC,EC_XYZ,EC_123
}

Class ExceptionB{
    public ExceptionB(ExceptionB.ErrorCode errorCode){}
    setters...
    getters...
    public static enum ErrorCode{
        EC_DEF,EC_LOL,EC_456
}

在与包含 ExceptionA、ExceptionB、ExceptionC 对象的数组一起工作的循环中:我想使用它的构造函数来一般地构造一个 Exception 对象,而无需明确说明ExceptionX.ErrorCode.

Class<? extends Exception> expectedException = exception.getClass().getConstructor(Enum.class).newInstance(someErrorCodeEnum);

问题发生在 getConstructor()。每个 Exception 类都存在构造函数,但它们采用 SpecificException.ErrorCode 类型。不仅仅是一个通用的 Enum.class。有没有可能像这样工作的方法?:

ExceptionA exceptionAobject = new ExceptionA(EC_ABC);
exceptionAobject.getEnumClassFromString("ErrorCode"); // Should be of type ExceptionA.ErrorCode
4

2 回答 2

1

这取决于具体情况。如果您确定只有一个构造函数,您可以简单地调用,例如ExceptionA.class.getConstructors()[0]获取唯一的构造函数。您甚至可以调用getParameterTypes()[0]构造函数对象来获取实际ErrorCode类型。

否则,如果您知道应该有一个名为 的内部类ErrorCode,则必须使用内部类的二进制名称,即

Class<? extends Exception> exceptionType = exception.getClass();
Class<?> errorCodeType = exceptionType.getClassLoader()
                        .loadClass(exceptionType.getName()+"$ErrorCode");
assert errorCodeType.getDeclaringClass() == exceptionType;

然后,您可以使用查找构造函数

Constructor<? extends Exception> con = exceptionType.getConstructor(errorCodeType);

但也许你想得太复杂了。如果您已经有了someErrorCodeEnum要传递给构造函数的对象,则可以简单地使用此对象来确定参数类型:

Constructor<? extends Exception> con = exception.getClass()
    .getConstructor(((Enum<?>)someErrorCodeEnum).getDeclaringClass());

请注意使用Enum.getDeclaringClass()而不是Object.getClass()此处的重要性,因为特定enum常量可能是扩展正式enum类型的匿名内部类。getDeclaringClass()将返回正确的类型。

于 2017-01-09T19:22:20.633 回答
0

我不太确定我是否满足您的要求。我认为这应该是可行的,无需反思,所以这是我的想法:

public class ExceptionA extends Exception {

    public ExceptionA(ExceptionA.ErrorCode errorCode) {
    }

    public static enum ErrorCode implements ExceptionErrorCode {
        EC_ABC, EC_XYZ, EC_123;

        @Override
        public Exception toException() {
            return new ExceptionA(this);
        }
    }
}

我正在使用这个小界面:

public interface ExceptionErrorCode {
    Exception toException();
}

这将允许类似:

    ExceptionErrorCode someErrorCodeEnum = ExceptionA.ErrorCode.EC_XYZ;
    Exception expectedException = someErrorCodeEnum.toException();

这能满足您的要求吗?

我正在考虑为了模型的缘故,您可能希望为您的异常类引入一个公共超类,因此您无需声明toException(),而expectedException只是Exception- 对于我的口味来说,这是一种模糊的类型。即使您没有立即看到需要,超类型也可能在一段时间内派上用场。

于 2017-01-09T20:35:55.513 回答