3

ループを使用して、呼び出しJExpressionで使用できるを作成する方法を見つけようとしています。.assign()JCodeModel のようなことができることは知っていますが、メソッド名のリストに基づいてJExpr.invoke("methodA").invoke("methodB")各メソッドを追加できるようにしたいと考えています。.invoke()誰もこれを行う方法を知っていますか?

私の Generator コードの例 [これは、ArrayList.add() メソッドを変更して ArrayList を返すことを前提としています]:

JDefinedClass newClass = jCodeModel._class("com.me.GeneratedClass");
JClass refObject = jCodeModel.ref(Object.class);
JClass refArrayList = jCodeModel.ref(ArrayList.class);

JFieldVar objectList = newClass.field(refArrayList, "objects");

JBlock methodBody = newClass.method(JMod.PUBLIC, refArrayList, "getNewObjectList");

String[] methodsToInvoke = {"add", "add", "add"};

JExpression rhsAssignmentExpression = JExpr._new(refArrayList).narrow(refObject);
for(String methodName : methodsToInvoke) {
    rhsAssignmentExpression.invoke(methodName).arg(JExpr._new(refObject));
}

methodBody.assign(objectList, rhsAssignmentExpression);
methodBody._return(objectList);

私が生成しようとしているものの例:

class GeneratedClass {

   ArrayList<Object> objects;

   public ArrayList<Object> getNewObjectList()
   {
      objects = new ArrayList<Object>().add(new Object()).add(new Object()).add(new Object());
      return objects;
   }
}

私の問題は、このメソッドが呼び出しメソッドを連鎖させず、それらを置き換えて、生成されたコードが次のようになることです。

class GeneratedClass {

   ArrayList<Object> objects;

   public ArrayList<Object> getNewObjectList()
   {
      objects = new ArrayList<Object>().add(new Object());
      return objects;
   }
}
4

2 に答える 2

1

これは、JCode オブジェクトを宣言する代わりに、JCodeModel に生の文字列を出力させることによっても実行できます。この特定の問題については、生成する必要がある java-imports がないため、directStatement() でこれを行うことができます。

StringBuilder expression = new StringBuilder();
expression.append (“objects = new ArrayList<Object>()”);

if ((methodsToInvoke != null) && (methodsToInvoke.length > 0))
{
   for(String methodName : methodsToInvoke)
   {
      expression.append(“.add(new Object())”);
   }
}

expression.append(“;”);

methodBoby.directStatement(expression.toString());
于 2014-03-20T18:42:04.783 に答える
0

必要なことは、各 invoke() JExpression 呼び出しの中間値を格納することです。

JExpression rhsAssignmentExpression = JExpr._new(refArrayList);
for(String methodName : methodsToInvoke) {
    rhsAssignmentExpression = rhsAssignmentExpression.invoke(methodName).arg(JExpr._new(refObject));
}

これにより、毎回呼び出しを再定義する必要がなくなり、効果的に呼び出しがチェーン化されます。結果は次のとおりです。

public class GeneratedClass {

    public ArrayList objects;

    public ArrayList getNewObjectList() {
        objects = new ArrayList().add(new Object()).add(new Object()).add(new Object());
        return objects;
    }

}
于 2014-03-21T01:38:22.113 に答える