从Class <! - ? - >获取子类

时间:2014-08-26 22:01:05

标签: java reflection google-reflections

我有一个项目,其中服务接口使用@Service注释(自定义注释,而不是Spring)进行注释,并且每个服务可以有多个实现(hibernate,mongodb等)。

我正在尝试使用这样的反射来加载实现类:

步骤1:使用@Service注释加载所有接口

步骤2:加载每个接口的所有子类

以下是代码:

public static void main(String[] args) throws Exception{
    Reflections reflections = new Reflections("net.jitix.cfs");
    //load annotated interfaces
    Set<Class<?>> types=reflections.getTypesAnnotatedWith(Service.class);

    Iterator<Class<?>> typeIterator=types.iterator();

    typeIterator.forEachRemaining(new Consumer<Class<?>>() {

        @Override
        public void accept(Class<?> type) {
            if(!type.isInterface()){
                typeIterator.remove();
            }
        }
    });

    for(Class<?> type:types){
        //load implementation classes
        Set<Class<?>> implTypes=reflections.getSubTypesOf(type); //error here
    }

    //rest of the code
}

我得到的编译错误:Type mismatch: cannot convert from Set<Class<? extends capture#8-of ?>> to Set<Class<?>>

根据我的understanding Class<?>表示该类型可以是任何内容,因此我很困惑为什么需要Class<T>的方法无法将Class<?>作为参数。

有谁能帮助我理解为什么会这样?我的方法有可能的替代方案吗?提前谢谢!

编辑:根据@MGorgon的评论和@StriplingWarrior以及@Sotirios Delimanolis使用反射法的答案是不可能的。有没有什么办法可以获得类型为Class<?>

的类型的子类型

2 个答案:

答案 0 :(得分:2)

这个问题的症结与反思无关,而是与协方差/逆差相关。它有效:

  

为什么我无法将Set<? extends Something>分配给Set<?>

答案是,如果你有一个Set<?>,那么编译器会允许你向该集添加任何类型的对象(比如说X),并且有人试图从如果原来的Set<? extends Something> 未延伸 X,原始Something会收到运行时错误。

这个原则可以更简单地证明:

Set<Dog> dogs = getDogs();
Set<Pet> pets = dogs;        // the compiler will complain here
pets.add(new Cat("Fluffy")); // to avoid letting this happen
for(Dog dog : dogs)         // which would cause an exception here
{
   ...
}

因为你(大概)知道你并不打算在这个集合中添加任何东西,所以告诉编译器你知道你通过一点点明确做了什么可能是安全的铸造:

Set<Class<?>> implTypes= (Set<Class<?>>)(Set<?>)reflections.getSubTypesOf(type);

答案 1 :(得分:1)

getSubTypesOf方法声明为

public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type) {

这是一种通用方法,将T声明为类型参数。调用方法时,方法调用会隐式或因为显式提供类型参数。

您使用Class<?>类型的参数调用了该方法。该方法将捕获?类型。因此,方法返回类型将变为Set<Class<? extends CAP of ?>>,即。一组某种未知类型的类,它是某种特定未知类型的子类型。

但是,您尝试将其分配给Set<Class<?>>,这是一组未知类型的类。但是这种未知类型不一定是某种特定未知类型的子类型。我知道当你大声说出来时没有多大意义,但请考虑?CAP of ?作为特定类型。这与尝试

相同
Set<Class<?>> implTypes = new HashSet<Class<Integer>>();

由于Classfinal,因此无法立即显示,因此无法将HashSet<Class<Integer>>分配给Set<Class<?>>,与ArrayList<ArrayList<Integer>不同{1}}无法分配给List<List<?>>

补充阅读: