java辅助创建动态类及其对象

java辅助创建动态类及其对象,java,reflection,Java,Reflection,我试图创建一个动态类及其对象,并试图使用对象调用类动态方法的方法,但我得到以下错误 java.lang.ClassNotFoundException: Eval 这是我的代码,请建议任何更改以使其成功运行 import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import javassist.CannotCompileException; import javassist.Cl

我试图创建一个动态类及其对象,并试图使用对象调用类动态方法的方法,但我得到以下错误

java.lang.ClassNotFoundException: Eval
这是我的代码,请建议任何更改以使其成功运行

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtNewMethod;
public class DyanamicClass {
/**
 * @param args
 */
public static void main (String[] args) throws Exception {

    createClass();
    Object obj=createObject();
    Object[] actualParams = new Object[] { new Double(17) };
    callMethod("eval", obj,actualParams);
}

public static void  createClass()
{
    ClassPool pool = ClassPool.getDefault();

    CtClass evalClass = pool.makeClass("Eval");

    try {
        evalClass.addMethod(
            CtNewMethod.make("public double eval (double x) { return x ; }", evalClass));

    } catch (CannotCompileException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public static Object createObject()
{
    Object obj=null;
    try {
        Class clazz = Class.forName("Eval");
        obj=clazz.newInstance();

    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return obj;
}

public static void callMethod(String name,Object obj,Object [] actualParams)
{
    Class[] formalParams = new Class[] { double.class };
    double result;
    try {
        Class clazz=Class.forName("Eval");

        Method meth = clazz.getDeclaredMethod(name, formalParams);

        result = ((Double) meth.invoke(obj, actualParams)).doubleValue();
        System.out.println(result);
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

}

您正试图在此处加载您的类:

Class clazz = Class.forName("Eval");
  • 确保类路径中有class
    Eval
  • 您必须给出
    packageName.className
    而不是类名
    Eval
    ,因此类似于
    org.test.Eval

  • 我已经在Javassist的实现中测试了一些东西。我不理解这个库,但我的假设是Class.forName()使用的类加载器(可能是当前的线程上下文类加载器-需要检查)找不到用于Eval的类文件,因为它的类路径上没有信息。我非常确定javassist具有需要为类设置的类路径信息,以便普通类装入器能够找到其类文件信息。此外,您可能需要将类文件保存到javassist提供的文件中

    但是,作为一种解决方法,请执行以下操作(注意,javassist表示在CtClass上调用toClass()后,不能再次使用它)

    CtClass ct =ClassPool.getDefault().getCtClass("Eval");
    System.out.println(ct);
    Class cl = ct.toClass();
    Object o  = cl.newInstance();
    Method m = cl.getDeclaredMethod("eval", new Class[]{double.class});
    Object res = m.invoke(o, 56);
    System.out.println(res);
    System.out.println(cl);
    System.out.println(Arrays.toString(cl.getDeclaredMethods()));