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,默認使用SubTypesScannerTypeAnnotationsScanner
也可以配置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); }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM