拥有此通用代码
static final <T> List<Class<? extends T>> findSubClasses(Class<T> clz, String packageName){
ClassPathScanningCandidateComponentProvider provider =
new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(clz));
Set<BeanDefinition> beanDefinitions = provider.findCandidateComponents(packageName);
List<Class<? extends T>> subClasses = beanDefinitions.stream().map(b->mapToClass(b, clz)).collect(Collectors.toList());
return subClasses;
}
private static final <T> Class<? extends T> mapToClass(BeanDefinition beanDefinition, Class<T> clz) {
String className = beanDefinition.getBeanClassName();
try {
return (Class<? extends T>) Class.forName(className);
} catch (ClassNotFoundException e) {
log.error("Failed to load the scanned class {}", className, e);
}
return null;
}
我在b->mapToClass(b, clz)
Bad return type in lambda expression: Class<capture of ? extends T> cannot be converted to Class<Object>
如何解决这个问题?
答案 0 :(得分:4)
这是编译器 IntelliJ无法正确推断map()
操作的返回类型的情况。
您可以通过简单地提供新的流项目类型来帮助它:Class<? extends T>
,如下所示:
List<Class<? extends T>> subClasses = beanDefinitions.stream()
.<Class<? extends T>>map(b-> mapToClass(b, clz))
.collect(Collectors.toList());
请注意,它似乎只是IntelliJ中的一个错误,因为javac似乎很乐意编译它(正如预期的那样)。
作为副节点,您可以通过以下方式避免mapToClass()
中未经检查的强制转换:
return Class.forName(className).asSubclass(clz);
答案 1 :(得分:0)
您提供给这些方法的通用信息是不相关的,即使您为它们指定了相同的名称(T
)。如果你想让它们以某种方式相关,你需要在类级别声明它们。
但在这种情况下它不起作用,因为你的方法是static
;因此,这将起作用:
public class YourClass<T> {
final List<Class<? extends T>> findSubClasses(Class<T> clz, String packageName) {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(clz));
Set<BeanDefinition> beanDefinitions = provider.findCandidateComponents(packageName);
List<Class<? extends T>> subClasses = beanDefinitions.stream().map(b -> mapToClass(b, clz))
.collect(Collectors.toList());
return subClasses;
}
private final Class<? extends T> mapToClass(BeanDefinition beanDefinition, Class<T> clz) {
String className = beanDefinition.getBeanClassName();
try {
return (Class<? extends T>) Class.forName(className);
} catch (ClassNotFoundException e) {
}
return null;
}
}
修改强>
确实Didier's points out这与javac-8
和javac-9
一样正常,因此根本不需要进行任何重构......