从运行时编译的类中调用抽象类的重写方法时发生AbstractMethodError

让我首先总结一下我到底想做什么。基本上,我使用JavaCompiler包在运行时编译扩展我的超类“ Player”的类。我唯一知道的是子类中的内容是它将扩展Player并覆盖抽象方法calcMove()。要在编译类后在运行时加载该类,我创建了一个URIclassloader对象以在创建类文件后对其进行加载。问题是当我尝试从实例化的对象运行calcMove方法时(通过使用java.lang.reflect)

基本上,这是我在做什么:

//to hold the compiler output
ByteArrayOutputStream compilerOut = new ByteArrayOutputStream();

                //compile
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

int compilationResult = compiler.run(null,compilerOut,playerFile.getabsolutePath());

if (compilationResult == 0) {

System.out.println("File " + playerFile.getName() + " compiled successfully");

} else {

//code 99 as compile error
System.err.println(compilerOut.toString());
system.exit(99);
}

文件编译完成后,我将使用此代码制作uriclassloader来加载类(上传文件夹包含源文件和类文件)。classname由文件名确定。然后,我使用java Reflection将类实例化为一个对象并将其强制转换为Player:

URL classUrl = new File("upload").toURI().toURL();

ClassLoader classLoader = URLClassLoader.newInstance(new URL[]{classUrl},ClassLoader.getSystemClassLoader());
                classLoader.loadClass(classname).asSubclass(Player.class);

Class<?> studentCustomClass = Class.forName(classname,true,classLoader);


Constructor<?> constructor = studentCustomClass.getconstructor();
Player studentPlayer = (Player) constructor.newInstance()

该实例化显然一直有效,直到我到达它称为calcMove的位置为止。我创建一个新的“ Game”类,该类接受2个Player参数,在这个Game类中,我从自定义类对象(以Player形式播放)中调用calcMove()方法。但是,我收到了AbstractMethodError异常,因为它试图从Player调用抽象的calcMove方法,而不是从子类中调用已实现的版本。

所以,我想知道,为什么要尝试从父类中调用抽象版本而不是我刚刚编译的类中的版本是有原因的? (据我所知,java认为我创建的对象是子类类的类型,而不仅仅是Player类,自从其抽象以来我就无法实例化它)现在,我正在使用java Reflection强制它可以从对象中调用calcMove功能

Method calcmove = players[0].getclass().getMethod("calcMove");

calcmove.invoke(players[0]);

出于安全原因,我现在想避免在代码中使用反射。那么为什么这样做有效,但这是

players[0].calcMove();

给我一​​个AbstractClassError吗?

chen22di 回答:从运行时编译的类中调用抽象类的重写方法时发生AbstractMethodError

我设法找到了可行的解决方案。如果我声明Player中的抽象方法calcMove受保护,那么它将正确地使用子类中的calcMove而不使用反射强制它。我假设这是因为它不能在Player中调用受保护的方法,所以它在子类中调用了public / package访问方法(因为被覆盖的方法可以比我发现的被覆盖的方法具有更高的可见性)我不确定为什么会这样。

本文链接:https://www.f2er.com/3164718.html

大家都在问