0


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

 Class Foo
     int a,b;
     String c;


对辅助函数的调用将是:

 void printCode(Foo.getClass())


该函数将跟踪对象的所有设置器,并将调用打印为文本,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% 的工作,停止条件应该是 - 获取原始类型或字符串类型 - 否则对对象使用递归。
我唯一缺少的是正确遍历设置器的实际递归逻辑, 需要伪代码方面的帮助,例如:

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;
}


谢谢!

4

1 回答 1

-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 方法。在 AspectJ 中,有一些切入点特别适用于 setter 方法和设置变量。如果您需要帮助,我认为我们可以找到正确的切入点。

于 2013-05-08T11:50:16.590 回答