在转换由Relections库生成的对象时抛出异常

时间:2017-11-11 11:11:42

标签: java generics reflection casting

基本上,我想要的是获得实现接口的所有类。但是,当我流式传输Reflections.getSubTypesOf返回的对象列表并进行转换时,我得到了:

java.lang.ClassCastException: Cannot cast java.lang.Class to com.czetsuya.api.error.ExceptionToErrorCode

以下是代码的一些部分:

返回从包中实现接口的类列表:

public static Set<Class<?>> getSubclasses(String packageName, Class parentClass) {
    Reflections reflections = new Reflections(packageName);
    return reflections.getSubTypesOf(parentClass);
}

投射返回的对象列表:

private Stream<ExceptionToErrorCode> implementations() {
    return ReflectionUtils.getSubclasses("com.weddinghighway.api", ExceptionToErrorCode.class).stream().map(p -> {
        return ExceptionToErrorCode.class.cast(p);
    });
}

执行过滤:

public ErrorCode of(Exception exception) {
    return implementations() //
        .filter(impl -> impl.canHandle(exception)) //
        .findFirst() //
        .map(impl -> impl.toErrorCode(exception)) //
        .orElse(ErrorCode.UnknownErrorCode.INSTANCE);
}

注意:我使用的是嵌套类,不确定它是否会导致某些内容:

public class GenericApiExceptionMappers {

    static class FileDoesNotExistsExceptionToErrorCode implements ExceptionToErrorCode {
        @Override
        public boolean canHandle(Exception exception) {
            return exception instanceof FileDoesNotExistsException;
        }

        @Override
        public ErrorCode toErrorCode(Exception exception) {
            return GenericApiErrorCodes.FILE_DOES_NOT_EXISTS;
        }
    }

    static class InvalidParameterExceptionToErrorCode implements ExceptionToErrorCode {
    }

}

1 个答案:

答案 0 :(得分:0)

而不是强制类,我所做的是实例化它。以下是对代码的更改:

private Stream<ExceptionToErrorCode> implementations() throws Exception {
    return ReflectionUtils.getSubclasses("com.czetsuya.api", ExceptionToErrorCode.class).stream().map(p -> {
        try {
            return ExceptionToErrorCode.class.cast(p.newInstance());
        } catch (InstantiationException | IllegalAccessException e) {
            return null;
        }
    });
}

由于异常导致实例化时,返回列表中可以包含空值,因此我们应该将其过滤掉。

public ErrorCode of(Exception exception) throws Exception {
    return implementations() //
        .filter(Objects::nonNull)//
        .filter(impl -> impl.canHandle(exception)) //
        .findFirst() //
        .map(impl -> impl.toErrorCode(exception)) //
        .orElse(ErrorCode.UnknownErrorCode.INSTANCE);
}