0

我过去曾使用Reflections库来查询类路径中具有特定注释或继承自特定类的类。使用反射很容易做到这一点,因为该库已经提供了回答此类特定查询的方法。

例如,下面的代码说明了如何查询继承自 的SomeType类和用 注释SomeAnnotation的类,查找位于包中的类my.package.prefix(示例取自 Reflection.java 类的文档):

Reflections reflections = new Reflections("my.package.prefix");
Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(SomeAnnotation.class);

但是,在我当前的问题中,我需要做的是查询具有任意属性集的类(例如,特定类名 + 现有注释 + 的组合)。我事先不知道这些属性,因为它们应该由程序员使用我正在开发的库来定义。

我设想解决方案的一部分类似于要求程序员定义一个带有布尔方法的 Strategy 类,以回答该类是否应该在答案集中。

例如,程序员应该实现一个类似于以下的接口:

public interface MyStrategy {
    public boolean match(Class clazz);
}

所以我的问题是,一旦我有了这个策略对象,我如何指示反射库过滤类,只保留那些根据程序员定义的策略类匹配的类?

更新:

显然过滤部分不是最困难的任务(感谢@MvG的回答),但实际上收集了所有要过滤的类(通常是程序员定义的一组基本包中的类)。所以想法是查询所有类,然后用方法过滤它们: ReflectionUtils.getAll(allClasses, predicate)

然后,为了获得要过滤的初始类集,我尝试查询Object程序员选择的特定包中的所有子类型。

在我用于此的代码下方:

ConfigurationBuilder config = new ConfigurationBuilder();
FilterBuilder fb = new FilterBuilder();
fb.include(FilterBuilder.prefix("my.package.prefix"));
config.filterInputsBy(fb);
config.setUrls(ClasspathHelper.forPackage("my.package.prefix"));
config.setScanners(new SubTypesScanner(false)); //the first argument at the constructor of SubTypesScanner indicates if the Object class should be ignored
Reflections reflections = new Reflections(config);
Set<Class<? extends Object>> unfilteredClasses = reflections.getSubTypesOf(Object.class);

这是最好(更有效)的解决方案吗?

有人有其他想法吗?提前致谢 !

4

1 回答 1

1

用于com.google.common.base.Predicate表达您的策略,或将您自己的策略对象包装到此类谓词中。然后你可以写

ReflectionUtils.getAll(allClasses, predicate);

似乎实际计算这个allClasses可迭代对象将是一项要求更高的任务。乍一看,我没有看到任何简单的 API。您可能必须直接访问底层存储,并Class自己将类名转换为对象。这意味着加载所有类,这可能非常耗时,甚至在某些情况下可能会失败。

于 2012-08-08T22:34:54.147 回答