java - 由于层次结构中的抽象类,使用反射的递归方法调用失败

标签 java inheritance recursion reflection abstract-class

我在底部简化了我在 SSCCE 中遇到的问题。

正如人们所期望的那样,输出是B C D。 例如,如果我创建 C 抽象,则打印 D ,然后发生异常:

java.lang.InstantiationException
    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at A.recursiveCall(A.java:22)
    at A.entryPoint(A.java:10)
    at A.main(A.java:6)

由于层次结构中的某些类必然是抽象的,因此我的代码会中断。

我能想到的唯一解决方案是删除 recursiveCall 方法并让 classSpecificMethod 调用父实现。

为了避免这引入的冗余和错误的可能性,我认为(我从未使用过它)我可以使用 AspectJ 在编译时生成代码。但这对我来说似乎太过分了。至少现在是这样,因为我没有其他用途。

如果没有其他方法可以用纯 Java 实现此目的,我也欢迎使用其他 JVM 语言和工具的答案。

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

abstract class A {
    public static void main(String[] args) {
        new D().entryPoint();
    }

    void entryPoint() {
        System.out.println(recursiveCall());
    }

    private String recursiveCall() {
        String result = "";
        Class<?> parentClass = getClass().getSuperclass();
        if (parentClass != A.class) {
            try {
                Constructor<?> baseConstructor = parentClass.getDeclaredConstructor();
                baseConstructor.setAccessible(true);
                @SuppressWarnings("unchecked")
                A baseInstance = (A) baseConstructor.newInstance();
                result = baseInstance.recursiveCall() + " ";
            }
            catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | InstantiationException ex) {
                ex.printStackTrace();
            }
        }
        result += classSpecificMethod();
        return result;
    }

    protected abstract String classSpecificMethod();

    static class B extends A {
        protected String classSpecificMethod() { return "B"; }
    }

    static class C extends B {
        protected String classSpecificMethod() { return "C"; }
    }

    static class D extends C {
        protected String classSpecificMethod() { return "D"; }
    }
}

最佳答案

您无法创建抽象类的实例。 我认为解决这个问题的唯一方法是让 recursiveCall() 跳过抽象类:

private String recursiveCall() {
    String result = "";
    Class<?> parentClass=getClass();
    do {
        parentClass = parentClass.getSuperclass();
    } while (Modifier.isAbstract(parentClass.getModifiers()) && parentClass != A.class);
    if (parentClass != A.class) {
        try {
            Constructor<?> baseConstructor = parentClass.getDeclaredConstructor();
            baseConstructor.setAccessible(true);
            @SuppressWarnings("unchecked")
            A baseInstance = (A) baseConstructor.newInstance();
            result = baseInstance.recursiveCall() + " ";
        }
        catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException | InstantiationException ex) {
            ex.printStackTrace();
        }
    }
    result += classSpecificMethod();
    return result;
}

关于java - 由于层次结构中的抽象类,使用反射的递归方法调用失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46349431/

相关文章:

Python 继承 : Is it necessary to explicitly call the parents constructor and destructor?

algorithm - 递归计算最接近的对

java - JAX-WS 服务的构造函数未调用

java - AsynchronousSocketChannel 一次性写入/读取所有消息

java - 批量修改Java代码文件——删除方法、注释等

java - 使用方法重载处理违反 'Liskov substitution principle' 的类

python - 从父类(super class)获取子类的名称?

java - 构建树中的 spring-security-core 版本冲突问题

algorithm - 想不通这个算法的通用名叫什么?

java - 帮助理解数学递归方法