Java 获取所有子类信息
我以前的博客(Java Scala获取注解的类信息)介绍过通过Reflections工具通过使用特定注解的类的信息,其实本工具也可以获取接口,抽象类,类等的所有子类信息。使用方法如下:
Reflections reflections = new Reflections("my.project"); Set<Class<? extends SomeType>> subTypes = reflections.getSubTypesOf(SomeType.class);
下面实例来说明如何使用的:
定义接口:
package test.reflection; /** * 类功能描述://TODO * * @author WangXueXing create at 19-5-4 下午10:16 * @version 1.0.0 */ public interface Base { void doSomeThing(); }
定义子类1:
package test.reflection; /** * 类功能描述://TODO * * @author WangXueXing create at 19-5-4 下午10:18 * @version 1.0.0 */ public class SubClass1 implements Base{ @Override public void doSomeThing() { System.out.println("SubClass1"); } }
定义子类2:
package test.reflection; /** * 类功能描述://TODO * * @author WangXueXing create at 19-5-4 下午10:18 * @version 1.0.0 */ public class SubClass2 implements Base{ @Override public void doSomeThing() { System.out.println("SubClass2"); } }
测试获取所有Base的子类信息:
package test.reflection; import org.reflections.Reflections; import java.util.Set; /** * 类功能描述://TODO * * @author WangXueXing create at 19-5-4 下午10:19 * @version 1.0.0 */ public class Test { public static void main(String[] args){ Reflections reflections = new Reflections("test.reflection"); Set<Class<? extends Base>> subTypes = reflections.getSubTypesOf(Base.class); subTypes.forEach(x -> System.out.println(x)); } }
结果输出如下:
class test.reflection.SubClass1
class test.reflection.SubClass2
如上如何获取所有子类信息。
其实Reflections还有其他很有用的功能,如下了解下:
一. Reflections的其他用法
使用默认的scanners,浏览url包含my.package的路径,包括以my.package开头的
Reflections reflections = new Reflections("my.package");
使用ConfigurationBuilder
new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage("my.project.prefix"))
.setScanners(new SubTypesScanner(),
new TypeAnnotationsScanner().filterResultsBy(optionalFilter), ...),
.filterInputsBy(new FilterBuilder().includePackage("my.project.prefix"))
...);
然后方便的使用查询方法,这要根据具体scanners配置
SubTypesScanner
Set<Class<? extends Module>> modules =
reflections.getSubTypesOf(com.google.inject.Module.class);
TypeAnnotationsScanner
Set<Class<?>> singletons =
reflections.getTypesAnnotatedWith(javax.inject.Singleton.class);
ResourcesScanner
Set<String> properties =
reflections.getResources(Pattern.compile(".*\\.properties"));
MethodAnnotationsScanner
Set<Method> resources =
reflections.getMethodsAnnotatedWith(javax.ws.rs.Path.class);
Set<Constructor> injectables =
reflections.getConstructorsAnnotatedWith(javax.inject.Inject.class);
FieldAnnotationsScanner
Set<Field> ids =
reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);
MethodParameterScanner
Set<Method> someMethods =
reflections.getMethodsMatchParams(long.class, int.class);
Set<Method> voidMethods =
reflections.getMethodsReturn(void.class);
Set<Method> pathParamMethods =
reflections.getMethodsWithAnyParamAnnotated(PathParam.class);
MethodParameterNamesScanner
List<String> parameterNames =
reflections.getMethodParamNames(Method.class)
MemberUsageScanner
Set<Member> usages =
reflections.getMethodUsages(Method.class)
如果没有配置scanner,默认使用SubTypesScanner
和TypeAnnotationsScanner
也可以配置Classloader,用来解析某些实时类
保证能够解析到url
git上的例子:https://github.com/ronmamo/reflections/tree/master/src/test/java/org/reflections
三. ReflectionUtils
ReflectionsUtils包含了一些方便的方法,形式类似*getAllXXX(type, withYYY)
比如
import static org.reflections.ReflectionUtils.*;
Set<Method> getters = getAllMethods(someClass,
withModifier(Modifier.PUBLIC), withPrefix("get"), withParametersCount(0));
//or
Set<Method> listMethodsFromCollectionToBoolean =
getAllMethods(List.class,
withParametersAssignableTo(Collection.class), withReturnType(boolean.class));
Set<Fields> fields = getAllFields(SomeClass.class, withAnnotation(annotation), withTypeAssignableTo(type));
四. ClasspathHelper
获取包、class、classloader的方法
使用maven可以很方便的集成到项目中,可以把浏览的元数据存储到xml/json文件中,下一次不必浏览,直接使用
在maven中,使用Reflections Maven plugin
插件
其他用法
- 并行查找url
- 序列化查找为xml/json
- 直接利用存储的元数据,快速load,不必再次scan
- 存储模型实体为.java文件,可以通过静态方式引用
types/fields/methods/annotation
- 初始化srping的包浏览
五. 注解的例子
获取包中,带TaskOption注解的类,然后获取注解的task()
Map<Class<? extends Task>, Class<?>> optionMap = new HashMap<>();
for (Class<?> clazz : reflections.getTypesAnnotatedWith(TaskOption.class)) {
TaskOption taskOption = clazz.getAnnotation(TaskOption.class);
if (taskOption == null) continue; // this shouldn't happen
optionMap.put(taskOption.task(), clazz);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 字符编码:从基础到乱码解决