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

问题描述 投票:0回答:1

让我先总结一下我到底想做什么。基本上,我使用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, 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吗?

java reflection classloader javacompiler abstractmethoderror
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.