2017-11-11 151 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); 
}