我正试图通过带有反射的Annotation标准收集类集(为了提高性能(:
Reflections reflections = new Reflections(packagePrefix);
Set<Class<Foo>> foos = reflections.getTypesAnnotatedWith(BooAnnotation.class);
问题是我得到的是Set<Class<?>>
而不是Set<Class<Foo>>
。通过使用.filter(Foo.class::isAssignableFrom)
筛选集合,我成功地检查了类是否是Foo
的类型。在这一点上,我知道我使用的是Foo
类型的类。不幸的是,当从Class<?>
转换为Class<Foo>
时,我得到了未选中的转换,我希望避免这种情况。
以下是完整的代码块:
Reflections reflections = new Reflections(packagePrefix);
Set<Class<Foo>> foos = reflections.getTypesAnnotatedWith(BooAnnotation.class)
.stream()
.filter(Foo.class::isAssignableFrom)
.map(uncheckedFoo -> {
@SuppressWarnings("unchecked")
Class<Foo> foo = (Class<Foo>) uncheckedFoo;
return foo;
})
.collect(Collectors.toSet());
对此有什么建议吗?
首先,Class<Foo>
用于类对象,它完全表示类Foo
,而不是其他类。只能有一个类型为Class<Foo>
的对象。因此,拥有他们的Set
是没有意义的。看起来您正在收集代表Foo
及其子类的类对象的Set
。在这种情况下,它应该是Set<Class<? extends Foo>>
。
其次,您需要获得类型为Class<?>
到Class<? extends Foo>
的uncheckedFoo
。如果您不想使用未检查的强制转换,可以使用Class::asSubclass()
以类型安全的方式执行此操作。所以你可以做一些类似的事情:
Set<Class<? extends Foo>> foos = reflections.getTypesAnnotatedWith(BooAnnotation.class)
.stream()
.filter(Foo.class::isAssignableFrom)
.map(uncheckedFoo -> uncheckedFoo.asSubclass(Foo.class))
.collect(Collectors.toSet());
您可以使用一个好的旧循环而不是流,以便在强制转换时向编译器明确每个项都是assignableFrom
Foo
。否则,它在下一步中忘记所有项目都是Foo
类型。
铸件检查和铸造必须在一个步骤中
Set<Class<Foo>> foos = new HashSet<>();
for(Class<?> i : reflections.getTypesAnnotatedWith(
BooAnnotation.class ) )
{
if(Foo.class.isAssignableFrom(i))
{
foos.add(Foo.class.cast(i)); //cast from Foo.class
}
}
注意:您可以使用forEach
而不是for(:)
循环