Add JExpression (JOp.cond()) to JBlock (JMethod body)

338 views Asked by At

I want to refactor an if - else statement into a Ternary Operator.

if ((variable) == null) { ... do something } else { ... do something else }

Creating a Ternary Operator with Codemodel is quite simple, as with JOp.cond() we can pass in the condition, ifTrue and ifFalse parameters to return a ternary statement.

My issue is with adding a JExpression into a method body (JBlock):

private void printSomeObject(final JMethod toStringMethod, FieldOutline fo) {
    String property = fo.getPropertyInfo().getName(false);
    JBlock block = toStringMethod.body();

    JExpression cond = JExpr.direct(property).eq(JExpr._null());
    JExpression ifTrue = JExpr.direct("... do something");
    JExpression ifFalse = JExpr.direct("... do something else");
    JExpression ternary = JOp.cond(cond, ifTrue, ifFalse);
    // toStringMethod.body().add(generateBody(ternary)); ONLY WORKS WITH JSTATEMENT
    ...
}

Has anyone an idea as to how to add a JExpression to a JBlock?

2

There are 2 answers

2
John Ericksen On BEST ANSWER

A ternary operator is used as a statement that returns a value. It is not a direct replacement for an if/else block.

Try compiling the following, it will fail:

1 == 1 ? System.out.pritln("true") : System.out.println("false");

JCodeModel is correct here in requiring the ternary to be a JExpression. To add it to a JBlock you need to assign it to a variable:

JDefinedClass output = codeModel._class(JMod.PUBLIC, "org.Test", ClassType.CLASS);
JMethod method = output.method(JMod.PUBLIC, codeModel.VOID, "test");
method.body().decl(codeModel.ref(String.class), "value", JOp.cond(JExpr.lit(1).eq(JExpr.lit(1)), JExpr.lit("true"), JExpr.lit("false")));

generates:

public class Test {

    public void test() {
        String value = ((1 == 1)?"true":"false");
    }

}
0
coderwurst On

Carrying on from @John Ericksen's comment, the following code will allow you to add a ternary operator within a method call, for example, to StringBuilder.append()

    JExpression expr = JOp.cond(JExpr.lit(1).eq(JExpr.lit(1)), JExpr.lit("true"), JExpr.lit("false"));
    JConditional conditional = method.body()._if(JExpr.lit(x).ne(JExpr._null()));
    conditional._then().add(out.invoke("append").arg(expr1));

generates

if (x != null) { 
   out.append(((1 == 1)?"true":"false"));
}