【问题标题】:Searching for Java class in a package recursively by name按名称递归搜索包中的Java类
【发布时间】:2011-06-02 02:03:06
【问题描述】:

是否有一些简单的、经过充分探索的方法可以在包中按名称搜索给定类,并递归地在 this 包的所有子包中搜索?

即给定现有的类,例如:

  • foo.MyClass
  • foo.bar.baz.some.more.MyClass
  • foo.bar.baz.some.more.OtherClass

我想运行magicMethod("foo.bar.baz", "MyClass") 之类的东西并得到Class foo.bar.baz.some.more.MyClass 作为结果。

显然,手动实现相当容易 - 通过探索从 Package.getPackages() 加载的包,过滤任何合适的内容并使用 Class.forName(...) 在循环中寻找类 - 但标准 Java 库或其他一些广泛使用的库中可能存在某些内容解决此任务的库,例如 Apache Commons?

【问题讨论】:

  • 公共 Java API 没有为此提供任何东西。包始终是 Java 中类标识的一个组成部分。据我所知,没有一个 API 函数可以接受或返回与其分开的类名。

标签: java reflection


【解决方案1】:

我自己的 OSS 软件的无耻插件:https://bitbucket.org/stevevls/metapossum-scanner/wiki,在 maven Central 中可用。

这个库的典型用例是做一些事情,比如寻找这样的实现类:

Set<Class<? extends MyDiscoverableHelper>> implementingClasses = new ClassesInPackageScanner()
    .findImplementers("com.mypackage.service.impl", MyDiscoverableHelper.class);

或像这样带注释的类:

Set<Class> entityClasses = new ClassesInPackageScanner()
    .findAnnotatedClasses("com.mypackage.datamodel", javax.persistence.Entity.class);

但是选择策略可以通过实现一个接口并将其传递给扫描仪来交换。如果您尝试按名称查找类,则代码 sn-p 将如下所示:

Set<Class> entityClasses = new ClassesInPackageScanner().setResourceNameFilter(new ResourceNameFilter() {
    public boolean acceptResourceName(java.lang.String packageName, java.lang.String fileName) {
        return fileName.equals("MyClass.class");
    }
}).scan("foo");

我不久前编写了这个库,因为我从来没有找到我喜欢探索包的实现。有许多库都有自己的内部 API,但据我所知,没有任何东西可以将其打包成一个很好的 API。

另外,探索包实际上很难做到正确。它并不像一开始看起来那么简单!

【讨论】:

  • 谢谢!看起来这是可行的方法!手动探索Packages 被证明是非常棘手的,没错……
  • 非常好...如果您检查一下,我很乐意听到任何反馈。我可能很快就会发布一个小版本。谢谢!
  • 我已经检查了你的包 - 它工作完美,但我们已经解决了“字符串 ID => 类”的映射,因为其他一些主要是与业务逻辑相关的原因(我们有基于这些“字符串 ID”的其他一些东西,所以我们不得不使用生成器)。无论如何,感谢您的回答和出色的图书馆:)
猜你喜欢
  • 1970-01-01
  • 2022-01-11
  • 2019-10-25
  • 2011-08-11
  • 2021-12-31
  • 1970-01-01
  • 2020-05-05
  • 1970-01-01
相关资源
最近更新 更多