【问题标题】:Pseudo code to recursively construct java object using Reflection使用反射递归构造java对象的伪代码
【发布时间】:2013-04-23 16:24:59
【问题描述】:


我正在尝试为函数编写代码,以帮助我深度打印 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;
}


谢谢!

【问题讨论】:

  • printCode 正在执行时,设置器的参数不可用。也许你应该看看吸气剂?
  • 我只需要设置器参数类型 - 它可用..
  • 对不起,我误会了。
  • 我不明白你的实际问题。您想要检查您的伪代码还是想要将您的 Pseudocode 翻译成 Java 还是只想要 getAllParameters(setter) 的逻辑?
  • 我正在寻找一个关于如何递归遍历对象并根据其设置器打印信息的想法,伪代码而不是代码。

标签: java dynamic reflection


【解决方案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参数的参数名称,你可以使用Parnamer http://paranamer.codehaus.org/

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

【讨论】:

  • 谢谢,但不需要实际代码,只是关于如何跟踪对象的伪代码。
  • 你在开玩笑吗?对你来说有什么不同?我应该删除修饰符还是什么? >:(我不知道你会用它做什么,但你可以像使用伪代码一样将它用作模板。
  • 在第二个示例中运行您的代码,它不会正确打印。
  • 然后指定不正确打印的内容和应该打印的内容
  • @user648026 如果你不描述你想要什么,没有人可以帮助你。
猜你喜欢
  • 1970-01-01
  • 2015-11-18
  • 2011-02-07
  • 2012-10-03
  • 2022-01-24
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 2016-01-24
相关资源
最近更新 更多