[英]Recursive method call that uses reflection fails due to abstract class in hierarchy
I have simplified the issue I'm facing in the SSCCE at the bottom. 我简化了我在底部的SSCCE中面临的问题。
As it is the output is BCD
as one would expect. 因为它的输出是BCD
正如人们所期望的那样。 If I make, say, C
abstract then D
gets printed and after that an exception occurs: 如果我说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)
Since some of the classes in the hierarchy will necessarily be abstract then my code breaks. 由于层次结构中的某些类必然是抽象的,因此我的代码中断了。
The only solution I can come up with is to remove the recursiveCall
method and make classSpecificMethod
call the parent implementation. 我唯一能想到的解决方案是删除recursiveCall
方法,并使classSpecificMethod
调用父实现。
To avoid the redundancy and possibility for error that this introduces I think (I've never used it) I could use AspectJ to generate the code at compile time. 为了避免引入冗余和出现错误的可能性,我认为(我从未使用过)我可以在编译时使用AspectJ生成代码。 But it seems overkill to me. 但是对我来说似乎太过分了。 At least for now since I don't have other uses for it. 至少到目前为止,因为我没有其他用途。
If there aren't other ways to do this in plain Java I also welcome answers that use other JVM languages and tools. 如果没有其他方法可以使用纯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"; }
}
}
You can't create an instance of an abstract class. 您不能创建抽象类的实例。 The only way I see to solve this is by making the recursiveCall() skip abstract classes: 我看到解决此问题的唯一方法是使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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.