0

I want to declare and instantiate a HashMap in one go in JCodeModel.

I do:

jc.field(JMod.PRIVATE, HashMap.class, "initAttributes");

which declares it but doesn't instantiate it. How do I instantiate it?

Thanks

More Than Five
  • 9,959
  • 21
  • 77
  • 127

1 Answers1

3

In the simplest case, you can just append the initialization directly to your creation of the field:

jc.field(JMod.PRIVATE, HashMap.class, "initAttributes")
    .init(JExpr._new(codeModel.ref(HashMap.class)));

Some further hints:

  • Considering that you should usually program to an interface, it is a good practice to declare the variable using a type that is "as basic as possible". You should hardly ever declare a variable as

    private HashMap map;
    

    but basically always only as

    private Map map;
    

    because Map is the interface that is relevant here.

  • You can also add generics in JCodeModel. These usually involve some calls to narrow on certain types. It is a bit more effort, but it will generate code that can be compiled without causing warnings due to the raw types.

An example is shown here. (It uses String as the key type and Integer as the value type of the map. You may adjust this accordingly)

import java.util.HashMap;
import java.util.Map;

import com.sun.codemodel.CodeWriter;
import com.sun.codemodel.JClass;
import com.sun.codemodel.JCodeModel;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JExpr;
import com.sun.codemodel.JMod;
import com.sun.codemodel.writer.SingleStreamCodeWriter;

public class InitializeFieldInCodeModel
{
    public static void main(String[] args) throws Exception
    {
        JCodeModel codeModel = new JCodeModel();
        JDefinedClass definedClass = codeModel._class("com.example.Example");

        JClass keyType = codeModel.ref(String.class);
        JClass valueType = codeModel.ref(Integer.class);
        JClass mapClass = 
            codeModel.ref(Map.class).narrow(keyType, valueType);
        JClass hashMapClass =
            codeModel.ref(HashMap.class).narrow(keyType, valueType);
        definedClass.field(JMod.PRIVATE, mapClass, "initAttributes")
            .init(JExpr._new(hashMapClass));

        CodeWriter codeWriter = new SingleStreamCodeWriter(System.out);
        codeModel.build(codeWriter);
    }

}

The generated class looks as follows:

package com.example;

import java.util.HashMap;
import java.util.Map;

public class Example {

    private Map<String, Integer> initAttributes = new HashMap<String, Integer>();

}
Marco13
  • 53,703
  • 9
  • 80
  • 159