我在底部简化了我在 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/