pagetop
Javablog
by Java coders, for Java codersRSS

Reducing Java Boilerplate

October 20th, 2009 by Sam

One of the darker sides of Java is the boilerplate; lines and lines of boring, repetitious and ugly boilerplate. In this post, we show how to reduce/hide boilerplate and increase the readability of your Java code under the following circumstances:

resulting in making your code more coherent .

Argument checking

The Google Collections provides a superb adjunct library to the Java Standard Library. Among the library is the beautiful convenience class Preconditions, full of static methods for testing conditions, throwing exceptions on failure. The following examples, interspersed with comments, demonstrates use

// bounds on integer, failure throws IllegalArgumentException
Preconditions.checkArgument(a > 0 && a <= 10);
// same as above, include value of 'a' in exception
Preconditions.checkArgument(a > 0 && a <= 10, a);
// use a static import and a formatter for output
checkArgument(count > 0, "must be positive: %s", count);
// throws NullPointerException if 'obj' is null
Preconditions.checkNotNull(obj);
// same as above but include string "obj" in exception
Preconditions.checkNotNull(obj, "obj");

contrast to how the same would be written without the convenience class. The vanilla boilerplate is so tedious, it is tempting to forego it.

if (!(a > 0 && a <= 10)) {
    throw new IllegalArgumentException();
}
if (!(a > 0 && a <= 10)) {
    throw new IllegalArgumentException(Integer.toString(a));
}
if (count <= 0) {
    throw new IllegalArgumentException(String.format("must be positive: %s", count));
}
if (obj == null) {
    throw new NullPointerException();
}
if (obj == null) {
    throw new NullPointerException("obj");
}

Using the Google Collections therefore encourages argument checking and, by implication, early detection of bugs.

equals and hashCode

Every good Java programmer should read Josh Bloch’s Effective Java and know the rules when overriding equals and hashCode. Although many modern IDEs simplify this by auto-generating boilerplate, the result is always hideous.

However, Google Collections provides static convenience methods in Objects which allow us to produce readable code. Consider Brian Goetz’s example from the IBM tutorial

@Override
public boolean equals(Object other) {
    if (this == other)
      return true;
    if (!(other instanceof A))
      return false;
    A otherA = (A) other;
    return 
      (someNonNullField.equals(otherA.someNonNullField))
        && ((someOtherField == null) 
            ? otherA.someOtherField == null 
            : someOtherField.equals(otherA.someOtherField)));
  }
 
@Override
public int hashCode() { 
    int hash = 1;
    hash = hash * 31 + someNonNullField.hashCode();
    hash = hash * 31 
                + (someOtherField == null ? 0 : someOtherField.hashCode());
    return hash;
  }

whereas the Google Collections equivalent is

@Override
public boolean equals(Object other) {
    if (this == other)
      return true;
    if (!(other instanceof A))
      return false;
    A otherA = (A) other;
    return Objects.equal(someNonNullField, otherA.someNonNullField)
        && Objects.equal(someOtherField, otherA.someOtherField);
}
 
@Override
public int hashCode() {
    return Objects.hashCode(someNonNullField, someOtherField);
}

Admittedly, that’s a lot of code to say two objects are equal, but it’s certainly more readable. In NetBeans, consider writing a Code Template to provide the reduced boilerplate outline.

If you are not happy having to look at this much code, consider combining with the final hint, for hiding getters and setters, perhaps even just for the first five lines of the equals method. The following is my NetBeans Code Template for equals and hashCode

@Override
public boolean equals(Object obj) {
    // <editor-fold defaultstate="collapsed" desc="boilerplate identity, instanceof and cast">
    if (this == obj)
        return true;
    if (!(obj instanceof ${TYPE default="Object"}))
        return false;
    final ${TYPE default="Object"} other = (${TYPE default="Object"}) obj;// </editor-fold>
    return Objects.equal(a, other.a);
}
 
@Override
public int hashCode() {
    return Objects.hashCode(a);
}

Getters and Setters

The JavaBeans pattern is a real bore. It demands getter and setter methods (with their own Javadocs!) to go along with fields… that’s 14 lines of code additional to every field you want to make available!

There is no way to get around writing this code. I recommend getting your IDE to auto-generate it. However, in NetBeans it is possible to wrap large portions of your files in Editor Fold comments, like so

// <editor-fold defaultstate="collapsed" desc="boilerplate">
/**
 * @return
 */
public A getA() {
    return a;
}
/**
 * @param a
 */
public void setA(A a) {
    this.a = a;
}
//</editor-fold>

and, so long as Preferences -> Editor -> General -> Code Folding is enabled, the code is folded up and hidden away from view. Only a line of text, labelled boilerplate appears in your file, and it can be uncovered with a single click.


This entry was posted by by Sam on Tuesday, October 20th, 2009 at 11:24 pm, and is filed under Google, Java, NetBeans. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.



2 comments on “Reducing Java Boilerplate”

Or, you could just write it in Scala instead? :-)

(actually, seriously, the more I see of Scala, the more I like it. I struggle to see why I would ever write something in Java when I could do so in Scala…)

Project Lombok goes a step further…Haven’t tried it yet but it looks interesting.

http://www.devx.com/Java/Article/42946

http://projectlombok.org/

Leave a comment

Markdown is supported.

To include code snippets in your comment, use

<pre><code># lang java
... code here ...
</code></pre>

or use 4 spaces at the start of the line instead of using code and pre tags.

Comment feed: RSS