我正在应对以下CodeWars挑战:
https://www.codewars.com/kata/hack-22/train/java
下面就是我写的:
public static Yossarian loophole() throws Throwable {
ClassPool pool = ClassPool.getDefault();
//Loader cl = new Loader(pool);
CtClass yossarianClass = pool.get("Yossarian");
int modifiers = yossarianClass.getDeclaredMethod("isCrazy").getModifiers();
if(Modifier.isFinal(modifiers)) {
System.out.println("Removing Final");
int notFinalModifier = Modifier.clear(modifiers, Modifier.FINAL);
yossarianClass.getDeclaredMethod("isCrazy").setModifiers(notFinalModifier);
yossarianClass.rebuildClassFile();
}
final CtClass saneYossarianClass = ClassPool.getDefault().makeClass("SaneYossarian");
saneYossarianClass.setSuperclass(yossarianClass);
final CtMethod overrideMethod = CtNewMethod.make("public boolean isCrazy() { return true; }", saneYossarianClass);
saneYossarianClass.addMethod(overrideMethod);
final Class<?> aClass = saneYossarianClass.toClass(Yossarian.class.getClassLoader(), Yossarian.class.getProtectionDomain());
return (Yossarian) aClass.newInstance();
}
,我收到以下错误:
线程“ main”中的异常javassist.CannotCompileException:由java.lang.ClassFormatError:类SaneYossarian覆盖了最终方法isCrazy。()Z
这是没有意义的!我正是使用JavaAssist来修改原始类。我不是在寻找解决挑战的方法,而只是想了解在修改课程的步骤中我做错了什么。任何帮助表示赞赏。
UPDATE :我还尝试直接修改基类中的方法以返回true,
答案 0 :(得分:1)
代替
bootstrap = False
使用
final Class<?> aClass = saneYossarianClass.toClass(Yossarian.class.getClassLoader(), Yossarian.class.getProtectionDomain());
出于某些原因,这对我有用:
final Class<?> aClass = saneYossarianClass.toClass();
并且:
public final class SomeClassHavingFinals {
public final void sayHelloBoy() {
System.out.println("I am saying hello original");
}
}
输出
我被覆盖
因此它似乎正在工作。 IDK内部,但似乎toClass()导致文件定义被重建。