2017-11-11 105 views
0

基本上,我想要的是获得实现接口的所有类。但是,当我流中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 { 
    } 

} 
+6

您正在投射该类的* class *,而不是* *实例*。 –

+0

对不起,我不明白。 cast方法说:“将一个对象转换为由此Class对象表示的类或接口。”这意味着p正被转换为ExceptionToErrorCode类?我错过了什么吗?谢谢。 – czetsuya

+1

您正在查找所有的子类。你永远不会创建类的任何*实例*。 'Class.cast'是基于语言转换的等价反映。例如:'Object x = 10;整数i =(整数)x; Integer j = Integer.class.cast(x);' - 这是两种投射方式。就好像你正在试图做的那样:'Number n = Number.class.cast(Integer.class);'这不会起作用。 –

回答

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); 
}