使用Reflection递归构造java对象的伪代码

时间:2013-04-29 21:03:47

标签: java dynamic reflection


我正在尝试编写函数代码,这将帮助我深入打印一个java代码,这将帮助我构建一个给定的新java pojo的对象。
函数将获取类类型,它将打印初始化代码,
示例:对于具有2个int成员和一个String成员的类Foo:

 Class Foo
     int a,b;
     String c;

对辅助函数的调用将是:

 void printCode(Foo.getClass())


该函数将跟踪对象的所有setter,它将打印调用为文本,Foo类的函数输出将为:

 Foo foo = new Foo();
 foo.setA();
 foo.setB();
 foo.setC();





这个类(A,M,N)的另一个更复杂的例子:

Class A
    setFoo(int){};
    setBar(int){};
    setM(M class){};
    setN(N class){};
    setNAndM(M,N){};

Class M
    setBaz(String){}

Class N
    setQux(Float){}


功能签名将是:

void printCode(Class clazz)


对于起始类A所需的程序输出将是(输出为java代码为字符串):

M m1 = new M();
m1.setBaz(/*some random String here*/);

N n1 = new N();
m1.setQux(/*some random Floathere*/);

M m2 = new M();
m2.setBaz(/*some random String here*/);

N n2 = new N();
m2.setQux(/*some random Floathere*/);

A  a = new A();
a.setFoo(/*some random data here*/);
a.setBar(/*some random data here*/);
a.setM(m1 - /*object name from previous iteration*/);
a.setN(n1 - /*object name from previous iteration*/);
a.setNAndM(m2,n2 - /*object name from previous iteration*/);


我能够完成99%的工作,停止条件应该是 - 获取原始或字符串类型 - 否则使用递归作为对象..
我唯一缺少的是正确遍历setter的实际递归逻辑,希望得到Pseudo代码的帮助,如:

void **printCode**(Class clazz){
    list setters = getAllSetters(clazz);
    for each setter{
         list parameters = getAllParameters(setter);
              if not all parameters are primitive or string:
              for each setter{
                         if(parameter is not (String or primitive))
                                   **printCode**(parameter)
                             }
                }
             print construction code for the object here;
}


谢谢!

1 个答案:

答案 0 :(得分:-1)

我用你的伪代码制作了一个Java类。我希望这是你在寻找的东西:

public class ReflectionPrinter {

public static void printCode(Class<?> clazz) {

    Constructor<?>[] cons = clazz.getConstructors();
    List<Method> setters = getAllSetters(clazz);

    for (Method setter : setters) {

        Class<?>[] params = setter.getParameterTypes();

        for (Class<?> param : params) {

            if (!isPrimitiveOrString(param)) {
                printCode(param);
            }
        }
    }

    // print out
    for (Constructor<?> con : cons) {
        System.out.println("new " + con.getName() + "()");
    }

    for (Method setter : setters) {
        System.out.println(clazz.getSimpleName() + "." + setter.getName() + "()");
    }

    // skip
    System.out.println();

}

public static List<Method> getAllSetters(Class<?> clazz) {
    List<Method> setters = new ArrayList<Method>();

    for (Method m : clazz.getMethods()) {
        if (m.getName().startsWith("set")) {
            setters.add(m);
        }
    }

    return setters;
}

public static boolean isPrimitiveOrString(Class<?> paramClass) {

    return paramClass.isPrimitive() || String.class.equals(paramClass);
}

如果您还需要setter参数的参数名称,可以使用Paranamer http://paranamer.codehaus.org/

另一种可能性是使用AspectJ http://www.eclipse.org/aspectj/来跟踪所有构造函数和/或setter调用。但是它只会打印实际调用的setter方法。在AspectJ中,有一些切入点特别适用于setter方法和设置变量。如果你需要帮助,我想我们可以找到正确的切入点。