从泛型类中获取Enum类?

时间:2017-01-09 18:46:58

标签: java reflection enums java-8 getconstructor

假设我有几个类:

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

2 个答案:

答案 0 :(得分:1)

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

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

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()将返回正确的类型。

答案 1 :(得分: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 - 它是模糊的根据我的口味输入。即使你没有立即看到需要,超类型也可以派上用场。