如何通过JCodeModel为生成的Java类字段添加初始化语句?
Problem Statement
I'm using JCodeModel to generate Java classes from JSON. Right now, my code only creates basic private fields, but I want to add initialization logic like private MTextField email = new MTextField("Email"); to each field.
Here's my current field creation method:
public void createFields(Map<String, Object> properties, JDefinedClass jc, JCodeModel model) { for(String key : properties.keySet()){ // getType returns "MTextField", key is "Email" or "Name" String type = getType(prop.get(key)); String name = key; try { JType jt = model.parseType(type); JFieldVar field = jc.field(JMod.PRIVATE, jt, name); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
I want to extend this to include field initializations—can I do this with JFieldVar?
Solution
Absolutely! You don't need to extend JFieldVar directly to add initialization logic. JCodeModel's JDefinedClass.field() method accepts an optional fourth parameter for the initialization expression. Here's how to modify your method to generate the desired code:
public void createFields(Map<String, Object> properties, JDefinedClass jc, JCodeModel model) { for (Map.Entry<String, Object> entry : properties.entrySet()) { String fieldName = entry.getKey(); Object prop = entry.getValue(); String fieldTypeStr = getType(prop); try { // Parse the field type (e.g., MTextField) JType fieldType = model.parseType(fieldTypeStr); // Create the constructor call expression: new MTextField("FieldName") JExpression initExpr = JExpr._new(fieldType) .arg(JExpr.lit(fieldName)); // Pass the field name as a string argument // Create the field with the initialization expression JFieldVar field = jc.field(JMod.PRIVATE, fieldType, fieldName, initExpr); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Key Details
- Initialization Expression: We use
JExpr._new(fieldType)to create anewinstance call, then chain.arg(JExpr.lit(fieldName))to add the string literal parameter (like"Email"). - Field Creation: The fourth parameter in
jc.field()is the initialization expression—passinginitExprhere tells JCodeModel to append= new MTextField("Email")to the field declaration. - Flexibility: If you need a different constructor argument (e.g., a localized label instead of the field name), just replace
JExpr.lit(fieldName)with the appropriate expression (e.g.,JExpr.lit("Student Email")).
With this modification, your generated StudentForm class will include initialized fields exactly as you wanted:
package crud.vaadin; public class StudentForm extends AbstractForm<Person> { private MTextField Email = new MTextField("Email"); private MTextField Name = new MTextField("Name"); }
内容的提问来源于stack exchange,提问作者cookieDope

