2013-04-29 86 views
0


我正在嘗試編寫函數的代碼,它將幫助我深度打印將幫助我構建給定的新的Java POjo對象的Java代碼。
功能會得到一個類的類型和將打印的初始化代碼,
示例:對於類Foo 2個INT成員和一個字符串構件:使用反射遞歸構造Java對象的僞代碼

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


謝謝!

+0

當** printCode **正在執行時,設置者的參數不可用。也許你應該看看獲得者? – 2013-04-29 21:09:08

+0

我只需要setters參數類型 - 它可用.. – user648026 2013-05-01 00:05:55

+0

對不起,我誤解了。 – 2013-05-01 00:27:54

回答

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

如果您還需要二傳手參數的參數名稱,你可以使用Paranamer http://paranamer.codehaus.org/

另一種可能性是使用AspectJ http://www.eclipse.org/aspectj/來跟蹤所有構造函數和/或setter調用。但是它只會打印實際調用的setter方法。在AspectJ中,特別爲setter方法和設置變量提供了切入點。我想我們可以找到正確的切入點,如果你需要幫助。

+0

謝謝你,但不需要實際的代碼,只是僞代碼如何跟蹤對象。 – user648026 2013-05-09 18:16:39

+0

你在開玩笑嗎?你有什麼不同? 我應該刪除修飾符還是什麼? > :(: 我不知道你會怎麼做,但是你可以用它作爲你使用僞代碼的相同方式的模板。 – Thorben 2013-05-09 18:47:02

+0

在第二個例子上運行你的代碼,它不會正確打印。 – user648026 2013-05-09 19:59:06