首页 > 解决方案 > Javassist - CtMethod 方法体中的数值操作抛出 java.lang.VerifyError

问题描述

请参阅下面使用 javassist 创建类和方法的代码:

public Class generateClass(String className, String methodName)
            throws CannotCompileException, NotFoundException {
   ClassPool pool = ClassPool.getDefault();
   CtClass cc = pool.makeClass(className);

   ClassLoader classLoader = FormulaAPI.class.getClassLoader();
   pool.appendClassPath(new LoaderClassPath(classLoader));
   pool.importPackage("com.formula");

   String methodBody = "return ($w)($1.evaluate(\"L\") + 25.0);";

   CtClass apiClass = pool.get("com.formula.FormulaAPI");

   CtClass doubleWrapperClass = pool.get("java.lang.Double");

   CtMethod m = new CtMethod(doubleWrapperClass,methodName,new CtClass[]{apiClass},cc);
   m.setBody(methodBody);
   cc.addMethod(m);

   return cc.toClass();
}

调用此方法后,我收到错误:

线程“主”java.lang.VerifyError 中的异常:(类:公式,方法:公式 1 签名:(Lcom/formulabuilder/FormulaAPI;)Ljava/lang/Double;)函数中的返回类型错误

Javassist 不支持方法体中的数字运算吗?我正在尝试调用一个方法并在它返回值之前添加一个数字,如下所示:

String methodBody = "return ($w)($1.evaluate(\"L\") + 25.0);";

如何在方法体中实现 +、*、/、<、<= 等数字运算?

标签: javadynamicclassloaderjava-assist

解决方案


问题很可能是 javassist 不支持自动装箱。所以java.lang.Double不兼容double。数字运算符仅适用于原始类型。

因此,如果您想保留签名,您需要自己对对象/原语进行装箱/拆箱。

就像是

String methodBody = "return java.lang.Double.valueOf($1.evaluate(\"L\").doubleValue() + 25.0d);";

(如果可以返回,您可能需要添加null处理)evaluate()null


推荐阅读