投射由Relections库生成的对象时抛出的类异常
问题描述:
基本上,我想要的是获得实现接口的所有类。但是,当我流中Reflections.getSubTypesOf返回的对象列表,并做了演员,我得到:投射由Relections库生成的对象时抛出的类异常
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 {
}
}
答
相反铸造类的,我所做的就是实例化。下面是修改代码:
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);
}
您正在投射该类的* class *,而不是* *实例*。 –
对不起,我不明白。 cast方法说:“将一个对象转换为由此Class对象表示的类或接口。”这意味着p正被转换为ExceptionToErrorCode类?我错过了什么吗?谢谢。 – czetsuya
您正在查找所有的子类。你永远不会创建类的任何*实例*。 'Class.cast'是基于语言转换的等价反映。例如:'Object x = 10;整数i =(整数)x; Integer j = Integer.class.cast(x);' - 这是两种投射方式。就好像你正在试图做的那样:'Number n = Number.class.cast(Integer.class);'这不会起作用。 –