3

我在使用codemodel的代码生成类中有一个填充的arraylist(非codemodel),我想在生成的代码中使用它。有什么办法吗?它有点“穿越世界”,因为生成的代码不引用或不依赖于生成它的代码,但是我仍然想使用 arraylist 的值,而不必在遍历值时手动复制它价值......必须有一种方法来做到这一点,因为有字符串,数字等......?

我的示例代码如下:

private JMethod makeHeadersWrapper( String endPointName, ArrayList<BasicNameValuePair> headersList )
{

    JMethod wrapperMethod = definedClass.method( JMod.PUBLIC | JMod.STATIC, codeModel.ref( headersList.getClass() ).narrow( BasicNameValuePair.class ), StringUtils.formatName( "make" + endPointName + "Header", false, StringUtils.FormatType.UP_ENGLISH_WORDS ) );

    JVar headersListVar = wrapperMethod.body().decl( wrapperMethod.type(), "headersList", {X} ) );
    wrapperMethod.body()._return( headersListVar );

    return wrapperMethod;

}

正如您在我的作业声明中看到的那样,有一个 {X} 空白字段,这是我试图弄清楚如何编写的。话虽如此,{X} 应该引用 makeHeadersWrapper 签名中的“headersList”参数。有什么方法可以将变量的值引用为 {X} 并使其成为代码模型 JExpr(ession)?请帮我解决{X}!:P

真诚地感谢, 皮奥特

4

1 回答 1

3

基本上我不认为JExpression支持列表。它确实有一个JArray,但你仍然必须遍历headersList. 在 codemode-2.6 之前,没有方法 inJExprJExpression迭代列表。所以你不能摆脱迭代部分。因此,标准做法将是迭代headersList并添加初始化语句。

例如,假设您有一个 Namevalue 对,例如

public class BasicNameValuePair {
    private String name;
    private String value;

    public BasicNameValuePair(String name, String value) {
        this.name = name;
        this.value = value;
    }
    //getters & setters
}

并初始化为

List<BasicNameValuePair> headerList = new ArrayList<BasicNameValuePair>();
headerList.add(new BasicNameValuePair("1", "1"));
headerList.add(new BasicNameValuePair("2", "2"));
headerList.add(new BasicNameValuePair("3", "3"));
headerList.add(new BasicNameValuePair("4", "4"));

然后你可以生成你的方法体

private JMethod makeHeadersWrapper( String endPointName, List<BasicNameValuePair> headersList ) {

    JClass headerClass = codeModel.ref( headersList.getClass() ).narrow( BasicNameValuePair.class );
    JMethod wrapperMethod = definedClass.method( JMod.PUBLIC | JMod.STATIC, headerClass, ( "make" + endPointName + "Header") );

    JVar headersListVar = wrapperMethod.body().decl( wrapperMethod.type(), "headersList", JExpr._new(headerClass) );
    for(BasicNameValuePair nameValuePair : headersList) {
        wrapperMethod.body().add(headersListVar.invoke("add").arg(JExpr._new(nameValuePairClass).arg(nameValuePair.getName()).arg(nameValuePair.getValue())));
    }
    wrapperMethod.body()._return( headersListVar );

    return wrapperMethod;
}

这将生成代码

public static ArrayList<BasicNameValuePair> makeTestHeader() {
    ArrayList<BasicNameValuePair> headersList = new ArrayList<BasicNameValuePair>();
    headersList.add(new BasicNameValuePair("1", "1"));
    headersList.add(new BasicNameValuePair("2", "2"));
    headersList.add(new BasicNameValuePair("3", "3"));
    headersList.add(new BasicNameValuePair("4", "4"));
    return headersList;
}

但是ArrayList有一个使用{{ }}. 所以你可以声明像

List<String> lst = new ArrayList<String>(){{ add("1"); add("2"); add("3"); add("4"); }};

并且JExpr有一个direct()方法,我们可以直接传递源代码。使用这两者,我们可以生成如下代码。我不会推荐这种方法,但它是可能的。

private JMethod makeHeadersWrapper( String endPointName, List<BasicNameValuePair> headersList ) {
    JMethod wrapperMethod = definedClass.method( JMod.PUBLIC | JMod.STATIC, codeModel.ref( headersList.getClass() ).narrow( BasicNameValuePair.class ), ( "make" + endPointName + "Header") );

    JVar headersListVar = wrapperMethod.body().decl( wrapperMethod.type(), "headersList", JExpr.direct(generateListConstructor(headersList)) );
    wrapperMethod.body()._return( headersListVar );

    return wrapperMethod;

}

private String generateListConstructor(List<BasicNameValuePair> headersList) {
    StringBuilder listEpr = new StringBuilder("new ArrayList<scope.BasicNameValuePair>(){{");
    for(BasicNameValuePair nameValuePair : headersList) {
        listEpr.append("add(new BasicNameValuePair(\"").append(nameValuePair.getName()).append("\", \"").append(nameValuePair.getValue()).append("\")); ");
    }
    return listEpr.append("}}").toString();
}

这将产生

public static ArrayList<BasicNameValuePair> makeTestHeader() {
    ArrayList<BasicNameValuePair> headersList = (new ArrayList<scope.BasicNameValuePair>(){{add(new BasicNameValuePair("1", "1")); add(new BasicNameValuePair("2", "2")); add(new BasicNameValuePair("3", "3")); add(new BasicNameValuePair("4", "4")); }});
    return headersList;
}

这也是一个有效的 java 代码。

这个答案可能不是您正在寻找的确切答案,但它可能会给您一个继续前进的想法。希望这可以帮助。

于 2014-05-20T18:10:35.390 回答