Search code examples
sun-codemodeljcodemodel

How to narrow a anonymous class?


i want to generate some code like below:

AbstractSomeClass<?> someClassObj = new AbstractSomeClass<MyConcreteType> {
    ...
}

I tried the following:

JDefinedClass anonymousSomeClass = codeModel.anonymousClass(AbstractSomeClass.class);
...
conditionalBody.decl(anonymousSomeClass, "someClassObj", JExpr._new(anonymousSomeClass.narrow(jClass)));

Got exception below, caused by ’anonymousSomeClass.narrow(jClass)‘. if i remove '.narrow(jClass)', everything goes fine.

java.lang.NullPointerException
    at com.sun.codemodel.JDefinedClass.outer(JDefinedClass.java:776)
    at com.sun.codemodel.JFormatter.t(JFormatter.java:280)
    at com.sun.codemodel.JNarrowedClass.generate(JNarrowedClass.java:143)
    at com.sun.codemodel.JFormatter.g(JFormatter.java:350)
    at com.sun.codemodel.JInvocation.generate(JInvocation.java:173)
    at com.sun.codemodel.JFormatter.g(JFormatter.java:350)
    at com.sun.codemodel.JVar.bind(JVar.java:212)
    at com.sun.codemodel.JFormatter.b(JFormatter.java:396)
    at com.sun.codemodel.JVar.declare(JVar.java:216)
        ...

Thanks.


Solution

  • This seems to be a bug in the way CodeModel handles anonymous classes and their ownership. There is a way around this, however, by narrowing the class before you treat it as an anonymous type:

        JDefinedClass tester = codeModel._class("Tester");
    
        JClass jClass = codeModel.ref(Reference.class);
        JClass unnarrowed =  codeModel.ref(AbstractSomeClass.class).narrow(codeModel.wildcard());
        JClass narrowed = codeModel.ref(AbstractSomeClass.class).narrow(jClass);
    
        JClass anonymous = codeModel.anonymousClass(narrowed);
    
        tester.field(JMod.PUBLIC, unnarrowed, "someClassObj", JExpr._new(anonymous));
    

    Gives:

    import test.Tester.AbstractSomeClass;
    
    public class Tester {
    
        public test.Tester.AbstractSomeClass<?> someClassObj = new AbstractSomeClass<Reference>() {
    
    
        }
        ;
    
    }