javagenericsmethod-invocationsun-codemodel

Sun Codemodel generic method invocation


I'm using Codemodel library for java-class generation. Is there a way to generate a generic method invocation which looks like this:

clazz.<String>get(value)

There is certainly a way of just casting a return result to a correct type using the following expression:

JExpr.cast(stringType, clazz.invoke("get").arg(value))

which results in

(String) clazz.get(value)

but the preferred way of casting is the first one, as this code is generating templates for further manual editing by developers.


Solution

  • With the existing JCodeModel API, there is no pre-built way to handle this. You can, however, define your own JStatement type to generate the generic declaration like this:

        JDefinedClass definedClass = codeModel._class(JMod.PUBLIC, "org.test.Tester", ClassType.CLASS);
    
        JMethod method = definedClass.method(JMod.PUBLIC, codeModel.VOID, "test");
    
        final JType targetType = codeModel.ref(String.class);
        final JVar clazzVar = method.body().decl(codeModel.ref(Class.class), "clazz", JExpr.invoke("getClass"));
    
        method.body().add(new JStatement(){
            @Override
            public void state(JFormatter f) {
                f.g(clazzVar).p(".<").g(targetType).p(">").p("get").p("();").nl();
            }
        });
    

    Which generates:

    package org.test;
    
    public class Tester {
    
        public void test() {
            Class clazz = getClass();
            clazz.<String >get();
        }
    }
    

    This is by no mean a complete solution (It's missing method call arguments for instance). Take a look at the implementation of the generate() method in JInvocation for the details that are required.