Java。如何获取具有反映的子类的所有实例(非类)?

时间:2019-01-17 14:59:47

标签: java reflection package

当然,我已经进行了一些研究,例如包扫描,java的反射,gson等。

我想要什么?

我想随机获取一些实例,但将此零件代码保留在子类中。

因此,每个子类应具有一个名为SuperClass nextInstance()的方法。 如果通过反射得到子类List,例如classes,我只需要为classes中的每个元素调用nextInstance。

就是这样。

但是,我需要为每个子类添加静态方法,并且名称必须为nextInstance,真正的愚蠢!!

我为什么要这样做。

我需要运行一个巨大的测试项目。 每个子类都有自己的参数(随机)。 我想隐藏参数设置。 同事无需关心参数是什么。 他们只需要关心自己的代码。 我认为实现此目标的唯一方法是从superClass扩展方法。

我所做的。

  • 为每个工厂创建一个工厂类(太麻烦)。
  • 在列表中添加子类路径以在运行时加载它们(难以维护)。
  • 通过反射尝试一种抽象的静态方法(在Java中是不可能的)。
  • 以此类推(也许是,我放弃了)

示例

    Abstract class SuperClass{
        // I know it is impossible in java, but just explain what I mean.
        public static abstract SuperClass nextInstance();
    }
    class SubClassA extend SuperClass{
        private double params;
        public SuperClass(double parmas){
            this.params = params;
        }
        public static SuperClass nextInstance(){
            return new SubClassA(r.nextDouble()+4);
        }
    }
    class SubClassB extend SuperClass{
        private int params;
        public SuperClass(int parmas){
            this.params = params;
        }
        public static SuperClass nextInstance(){
            return new SubClassB(r.nextInt(20)+4);
        }
    }
    class Main{
        public static void main(String[] args){
            List<Class> classes.....// get classes extend from SuperClass by reflection.
            List<SuperClass> res = new ArrayList<>();
            for(Class c:classes){
                res.add(c.nextInstance())
            }
            // do something on each element in res.
        }
    }

更新

我认为我需要更简单地重新解释我想做的事情。 如果有人使用过slfj LoggerFactory.getLogger(Class c),将会更容易理解。 对我来说,我需要实现一个Factory.getInstance(Class c)之类的方法,该方法中的代码将调用c.nextInstance();

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

好,因此您无法在超类中声明“公共静态抽象”方法,但是您可以告诉您的同事仅包含一个“公共静态”方法,该方法将返回SuperClass且不接受任何参数,然后查找通过工厂反射的方法:

public static class Main {
    public static void main(String[] args) {
        List<Class> classes.....// get classes extend from SuperClass by reflection.
        List<SuperClass> res = new ArrayList<>();
        for (Class<?> clazz : classes) {
            for (Method method : clazz.getMethods()) {
                if (isStatic(method) && returnsSuperClass(method) && hasNoParameters(method)) {
                    res.add((SuperClass) method.invoke(null));
                }
            }
        }
    }

    public static boolean hasNoParameters(Method method) {
        return method.getParameterTypes().length == 0;
    }

    public static boolean returnsSuperClass(Method method) {
        return SuperClass.class.isAssignableFrom(method.getReturnType());
    }

    public static boolean isStatic(Method method) {
        return (method.getModifiers() & Modifier.STATIC) == Modifier.STATIC;
    }
}