× {{alert.msg}} Never ask again
Get notified about new tutorials RECEIVE NEW TUTORIALS

How do I create a Builder that can build more than one kind of Java object?

John Feminella
Feb 02, 2015
<p>If you're asking for a single <code>Builder</code> type that doesn't need to know anything about the entities it operates on, Java can't easily do it the way you describe. In the <code>Builder&lt;User&gt;</code> example, the <code>withName</code> and <code>withAge</code> methods would need to be known at compile-time.</p> <p>Since those methods don't actually exist, but would need to be dynamically added, you'd have to write a custom class-loader. Once the <code>Builder</code> class is linked, you can't change it, and since it doesn't know what methods you want until you pass in an entity, it's too late to change at the point you need to add methods.</p> <p>You could get mostly there by using reflection. For instance, you could have a single method in <code>Builder</code> called, say, <code>with(String field, Class&lt;?&gt; c, Object value)</code>. Then, assuming the object instance you're building has a method named "set___", you can use the <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Method.html" rel="nofollow"><code>Method</code></a> class to invoke the corresponding set method with the value that was passed in.</p> <p>That would look something like:</p> <pre><code> Builder&lt;Account&gt; b = new Builder&lt;&gt;(); b.with("AccountNumber", String.class, "5897-1048-2949"); // this invokes "setAccountNumber" method on internal // Account instance with "5897-1048-2949" cast to String </code></pre> <p>A better idea is to have classes for thing you're going to build: <code>AccountBuilder</code>, <code>UserBuilder</code>, and so on. This is clearer and is probably the best you can do in Java without resorting to exotic solutions like custom class-loaders. (Yes, you'll have to write the properties for each one.)</p> <p>But if you decide you need to do a lot of building, you may want to consider an alternative language that makes this easier to pull off, like <a href="https://www.ruby-lang.org/en/" rel="nofollow">Ruby</a> or <a href="http://elixir-lang.org/" rel="nofollow">Elixir</a>. Dynamic methods are not Java's strong suit, and trying to circumvent a language's limitations just to achieve a particular API is generally a terrible idea.</p> <p>This tip was originally posted on <a href="http://stackoverflow.com/questions/25912679/How%20do%20I%20create%20a%20Builder%20that%20can%20build%20more%20than%20one%20kind%20of%20Java%20object?/25912950">Stack Overflow</a>.</p>
comments powered by Disqus