<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ generator - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ generator - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 30 May 2026 16:32:19 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/generator/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to generate data classes in Java ]]>
                </title>
                <description>
                    <![CDATA[ By Bertil Muth Kotlin has a concise syntax to declare data classes: data class User(val name: String, val age: Int) The equivalent Java syntax is verbose. You have to create a Java class with private fields. And getter and setter methods for the fie... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-generate-data-classes-in-java-fead8fa354a2/</link>
                <guid isPermaLink="false">66d45ddbc7632f8bfbf1e3eb</guid>
                
                    <category>
                        <![CDATA[ code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ generator ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 04 Dec 2018 17:59:46 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*upVmlEendf-ZejB-vCeh_g.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Bertil Muth</p>
<p>Kotlin has a concise syntax to declare data classes:</p>
<pre><code class="lang-kotlin"><span class="hljs-keyword">data</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span></span>(<span class="hljs-keyword">val</span> name: String, <span class="hljs-keyword">val</span> age: <span class="hljs-built_in">Int</span>)
</code></pre>
<p>The equivalent Java syntax is verbose. You have to create a Java class with private fields. And <code>getter</code> and <code>setter</code> methods for the fields. And additional methods like <code>equals()</code>, <code>hashCode()</code> and <code>toString()</code>.</p>
<p>But who says you have to create the Java code by hand?</p>
<p>In this article, I’ll show you how to generate Java source files from a <a target="_blank" href="https://en.wikipedia.org/wiki/YAML">YAML</a> file.</p>
<p>Here’s the example YAML file:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">User:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">Name</span>
    <span class="hljs-attr">age:</span> <span class="hljs-string">Integer</span>

<span class="hljs-attr">Name:</span>
    <span class="hljs-attr">firstName:</span> <span class="hljs-string">String</span>
    <span class="hljs-attr">lastName:</span> <span class="hljs-string">String</span>
</code></pre>
<p>The example output of the code generator is two Java source files, <code>User.java</code> and <code>Name.java</code>.</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span></span>{
    <span class="hljs-keyword">private</span> Name name;
    <span class="hljs-keyword">private</span> Integer age;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">User</span><span class="hljs-params">()</span></span>{
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> Name <span class="hljs-title">getName</span><span class="hljs-params">()</span></span>{
        <span class="hljs-keyword">return</span> name;
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span><span class="hljs-params">(Name name)</span></span>{
        <span class="hljs-keyword">this</span>.name = name;
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> Integer <span class="hljs-title">getAge</span><span class="hljs-params">()</span></span>{
        <span class="hljs-keyword">return</span> age;
    }
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAge</span><span class="hljs-params">(Integer age)</span></span>{
        <span class="hljs-keyword">this</span>.age = age;
    }
}
</code></pre>
<p><code>Name.java</code> is similar.</p>
<p>The point of this article is: You’ll learn how to program a code generator from scratch. And it’s easy to adapt it to your needs.</p>
<h3 id="heading-the-main-method">The main method</h3>
<p>The <code>[main()](https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/Main.java)</code> method does two things:</p>
<ul>
<li>Step 1: Read in the YAML file, into class specifications</li>
<li>Step 2: Generate Java source files from the class specifications</li>
</ul>
<p>It decouples reading and generating. You can change the input format in the future, or support more input formats.</p>
<p>Here’s the <code>main()</code> method:</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{
    <span class="hljs-comment">// Make sure there is exactly one command line argument, </span>
    <span class="hljs-comment">// the path to the YAML file</span>
    <span class="hljs-keyword">if</span> (args.length != <span class="hljs-number">1</span>) {
        System.out.println(<span class="hljs-string">"Please supply exactly one argument, the path to the YAML file."</span>);
        <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Get the YAML file's handle &amp; the directory it's contained in</span>
    <span class="hljs-comment">// (generated files will be placed there)</span>
    <span class="hljs-keyword">final</span> String yamlFilePath = args[<span class="hljs-number">0</span>];
    <span class="hljs-keyword">final</span> File yamlFile = <span class="hljs-keyword">new</span> File(yamlFilePath);
    <span class="hljs-keyword">final</span> File outputDirectory = yamlFile.getParentFile();

    <span class="hljs-comment">// Step 1: Read in the YAML file, into class specifications</span>
    YamlClassSpecificationReader yamlReader = <span class="hljs-keyword">new</span> YamlClassSpecificationReader();
    List&lt;ClassSpecification&gt; classSpecifications = yamlReader.read(yamlFile);

    <span class="hljs-comment">// Step 2: Generate Java source files from class specifications</span>
    JavaDataClassGenerator javaDataClassGenerator = <span class="hljs-keyword">new</span> JavaDataClassGenerator();
    javaDataClassGenerator.generateJavaSourceFiles(classSpecifications, outputDirectory);

    System.out.println(<span class="hljs-string">"Successfully generated files to: "</span> + outputDirectory.getAbsolutePath());
}
</code></pre>
<h3 id="heading-step-1-read-the-yaml-file-into-class-specifications">Step 1: Read the YAML file into class specifications</h3>
<p>Let me explain what happens in this line:</p>
<pre><code class="lang-java">List&lt;ClassSpecification&gt; classSpecifications =  yamlReader.read(yamlFile);
</code></pre>
<p>A class specification is a definition of a class to be generated and its fields.<br>Remember the <code>User</code> in the example YAML file?</p>
<pre><code class="lang-yaml"><span class="hljs-attr">User:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">Name</span>
    <span class="hljs-attr">age:</span> <span class="hljs-string">Integer</span>
</code></pre>
<p>When the <a target="_blank" href="https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/read/YamlClassSpecificationReader.java">YAML reader</a> reads that, it will create one <code>ClassSpecification</code> object, with the name <code>User</code>. And that class specification will reference two <code>FieldSpecification</code> objects, called <code>name</code> and <code>age</code>.</p>
<p>The code for the <code>ClassSpecification</code> class and the <code>FieldSpecification</code> class is simple.</p>
<p>The content of <code>[ClassSpecification.java](https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/model/ClassSpecification.java)</code> is shown below:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ClassSpecification</span> </span>{
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> List&lt;FieldSpecification&gt; fieldSpecifications;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ClassSpecification</span><span class="hljs-params">(String className, List&lt;FieldSpecification&gt; fieldSpecifications)</span> </span>{
        <span class="hljs-keyword">this</span>.name = className;
        <span class="hljs-keyword">this</span>.fieldSpecifications = fieldSpecifications;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> name;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;FieldSpecification&gt; <span class="hljs-title">getFieldSpecifications</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> Collections.unmodifiableList(fieldSpecifications);
    }
}
</code></pre>
<p>The content of <code>[FieldSpecification.java](https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/model/FieldSpecification.java)</code> is:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FieldSpecification</span> </span>{
    <span class="hljs-keyword">private</span> String name;
    <span class="hljs-keyword">private</span> String type;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">FieldSpecification</span><span class="hljs-params">(String fieldName, String fieldType)</span> </span>{
        <span class="hljs-keyword">this</span>.name = fieldName;
        <span class="hljs-keyword">this</span>.type = fieldType;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> name;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getType</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> type;
    }
}
</code></pre>
<p>The only remaining question for Step 1 is: how do you get from a YAML file to objects of these classes?</p>
<p>The <a target="_blank" href="https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/read/YamlClassSpecificationReader.java">YAML reader</a> uses the <a target="_blank" href="https://bitbucket.org/asomov/snakeyaml">SnakeYAML</a> library to parse YAML files.<br>SnakeYAML makes a YAML file’s content available in data structures like maps and lists.</p>
<p>For this article, you only need to understand maps — because that’s what we use in the YAML files.</p>
<p>Look at the example again:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">User:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">Name</span>
    <span class="hljs-attr">age:</span> <span class="hljs-string">Integer</span>

<span class="hljs-attr">Name:</span>
    <span class="hljs-attr">firstName:</span> <span class="hljs-string">String</span>
    <span class="hljs-attr">lastName:</span> <span class="hljs-string">String</span>
</code></pre>
<p>What you see here is two nested maps.</p>
<p>The key of the outer map is the class name (like <code>User</code>).</p>
<p>When you get the value for the <code>User</code> key, you get a map of the class fields:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Name</span>
<span class="hljs-attr">age:</span> <span class="hljs-string">Integer</span>
</code></pre>
<p>The key of this inner map is the field name, and the value is the field type.</p>
<p>It’s a map of strings to a map of strings to strings. That’s important to understand the code of the <a target="_blank" href="https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/read/YamlClassSpecificationReader.java">YAML reader</a>.</p>
<p>Here’s the method that reads in the complete YAML file contents:</p>
<pre><code class="lang-java"><span class="hljs-keyword">private</span> Map&lt;String, Map&lt;String, String&gt;&gt; readYamlClassSpecifications(Reader reader) {
    Yaml yaml = <span class="hljs-keyword">new</span> Yaml();

    <span class="hljs-comment">// Read in the complete YAML file to a map of strings to a map of strings to strings</span>
    Map&lt;String, Map&lt;String, String&gt;&gt; yamlClassSpecifications = 
        (Map&lt;String, Map&lt;String, String&gt;&gt;) yaml.load(reader);

    <span class="hljs-keyword">return</span> yamlClassSpecifications;
}
</code></pre>
<p>With the <code>yamlClassSpecifications</code> as input, the <a target="_blank" href="https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/read/YamlClassSpecificationReader.java">YAML reader</a> creates the <code>ClassSpecification</code> objects:</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">private</span> List&lt;ClassSpecification&gt; <span class="hljs-title">createClassSpecificationsFrom</span><span class="hljs-params">(Map&lt;String, Map&lt;String, String&gt;&gt; yamlClassSpecifications)</span> </span>{
    <span class="hljs-keyword">final</span> Map&lt;String, List&lt;FieldSpecification&gt;&gt; classNameToFieldSpecificationsMap 
        = createClassNameToFieldSpecificationsMap(yamlClassSpecifications);

    List&lt;ClassSpecification&gt; classSpecifications = 
        classNameToFieldSpecificationsMap.entrySet().stream()
            .map(e -&gt; <span class="hljs-keyword">new</span> ClassSpecification(e.getKey(), e.getValue()))
            .collect(toList());

    <span class="hljs-keyword">return</span> classSpecifications;
}
</code></pre>
<p>The <code>createClassNameToFieldSpecificationsMap()</code> method creates</p>
<ul>
<li>the field specifications for each class, and based on these</li>
<li>a map of each class name to its field specifications.</li>
</ul>
<p>Then the <a target="_blank" href="https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/read/YamlClassSpecificationReader.java">YAML reader</a> creates a <code>ClassSpecification</code> object for each entry in that map.</p>
<p>The contents of the YAML file are now available to Step 2 in a YAML independent way. We’re done with Step 1.</p>
<h3 id="heading-step-2-generate-java-source-files-from-the-class-specifications">Step 2: Generate Java source files from the class specifications</h3>
<p><a target="_blank" href="https://freemarker.apache.org/">Apache FreeMarker</a> is a Java template engine that produces textual output. Templates are written in the FreeMarker Template Language (FTL). It allows static text to mix with the content of Java objects.</p>
<p>Here’s the template to generate the Java source files, <code>[javadataclass.ftl](https://github.com/bertilmuth/javadataclass/blob/2c550c8ea0ab551d06eed342ea0013043f96f080/src/main/resources/javadataclass.ftl)</code>:</p>
<pre><code class="lang-ftl">public class ${classSpecification.name}{
&lt;#list classSpecification.fieldSpecifications as field&gt;
    private ${field.type} ${field.name};
&lt;/#list&gt;
    public ${classSpecification.name}(){
    }
&lt;#list classSpecification.fieldSpecifications as field&gt;
    public ${field.type} get${field.name?cap_first}(){
        return ${field.name};
    }
    public void set${field.name?cap_first}(${field.type} ${field.name}){
        this.${field.name} = ${field.name};
    }
&lt;/#list&gt;    
}
</code></pre>
<p>Let’s look at the first line:</p>
<pre><code>public <span class="hljs-class"><span class="hljs-keyword">class</span> $</span>{classSpecification.name}{
</code></pre><p>You can see it begins with the static text of a class declaration: <code>public class</code>. The interesting bit is in the middle: <code>${classSpecification.name}</code>.</p>
<p>When Freemarker processes the template, it accesses the <code>classSpecification</code> object in its model. It calls the <code>getName()</code> method on it.</p>
<p>What about this part of the template?</p>
<pre><code class="lang-ftl">&lt;#list classSpecification.fieldSpecifications as field&gt;
    private ${field.type} ${field.name};
&lt;/#list&gt;
</code></pre>
<p>At first, Freemarker calls <code>classSpecification.getFieldSpecifications()</code>. It then iterates over the field specifications.</p>
<p>One last thing. That line is a bit odd:</p>
<pre><code class="lang-ftl">public ${field.type} get${field.name?cap_first}(){
</code></pre>
<p>Let’s say the example field is <code>age: Integer</code> (in YAML). Freemarker translates this to:</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> Integer <span class="hljs-title">getAge</span><span class="hljs-params">()</span></span>{
</code></pre>
<p>So <code>?cap_first</code> means: capitalize the first letter, as the YAML file contains <code>age</code> in lower case letters.</p>
<p>Enough about templates. How do you generate the Java source files?</p>
<p>First, you need to configure FreeMarker by creating a <code>Configuration</code> instance. This happens in the constructor of the <code>[JavaDataClassGenerator](https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/generate/JavaDataClassGenerator.java)</code>:</p>
<p>To generate source files, the <code>[JavaDataClassGenerator](https://github.com/bertilmuth/javadataclass/blob/ee95965bc798ae5425083baf88c4750fb27ecf11/src/main/java/de/bertilmuth/javadataclass/generate/JavaDataClassGenerator.java)</code> iterates over the class specifications, and generates a source file for each:</p>
<p>And that’s it.</p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>I showed you how to build a Java source code generator based on YAML files. I picked YAML because it is easy to process, and thus easy to teach. You can replace it with another format if you like.</p>
<p>You can find the complete code on <a target="_blank" href="https://github.com/bertilmuth/javadataclass">Github</a>.</p>
<p>To make the code as understandable as possible, I took a few shortcuts:</p>
<ul>
<li>no methods like <code>equals()</code>, <code>hashCode()</code> and <code>toString()</code></li>
<li>no inheritance of data classes</li>
<li>generated Java classes are in the default package</li>
<li>the output directory is the same as the input directory</li>
<li>error handling hasn’t been my focus</li>
</ul>
<p>A production-ready solution would need to deal with those issues. Also, for data classes, <a target="_blank" href="https://projectlombok.org/">Project Lombok</a> is an alternative without code generation.</p>
<p>So think of this article as a beginning, not an end. Imagine what is possible. A few examples:</p>
<ul>
<li>scaffold JPA entity classes or Spring repositories</li>
<li>generate several classes from one specification, based on patterns in your application</li>
<li>generate code in different programming languages</li>
<li>produce documentation</li>
</ul>
<p>I currently use this approach to translate natural language requirements<br> directly to code, for research purposes. What will you do?</p>
<p><em>If you want to know what I’m hacking on, visit <a target="_blank" href="https://github.com/bertilmuth/requirementsascode">my GitHub project</a>.</em></p>
<p><em>You can contact me on <a target="_blank" href="https://twitter.com/BertilMuth">Twitter</a> or <a target="_blank" href="https://www.linkedin.com/in/bertilmuth">LinkedIn</a>.</em></p>
<p><em>The original version of this article was posted on <a target="_blank" href="https://dev.to/bertilmuth/generating-data-classes-in-java-4cef">dev.to</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
