zoukankan      html  css  js  c++  java
  • 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);
        }
  • 相关阅读:
    给最小化托盘增加右键菜单
    (转)c#实现开机自启动
    Socket代码
    (转)C# Socket简单例子(服务器与客户端通信)
    (转)C# Socket异步通信
    (转)winform pictureBox后台显示图片
    验证DataGridView单元格的值
    批处理判断是否有.net环境
    Winform判断是否已启动
    linux 下 apache启动、停止、重启命令
  • 原文地址:https://www.cnblogs.com/barrywxx/p/10810183.html
Copyright © 2011-2022 走看看