Today I would like to share with you my new technical companion: projectlombok.
What is lombok
ProjectLombok like Springfuse is a code generator, and I very much like code generators as they make my life easier.
Where springfuse is producing working knowledge spanning many technologies, project lombok produces simple code to bypass java excessive verbosity.
Project lombok is generating : setter, getter, toString, equals, hashCode.
While reading this you should think that eclipse does it for you already since... for ever.
You could also tell me that I should use a real language like scala or a dynamic language like groovy.
The problem
Well they could be ideal solutions, but like so many I have no choice but to stick with java.
Should we really rely on our IDE to generate this kind of code ?
Should we really have to see all these methods clutter our code ?
Should we really need to loose time and focus to manually verify that our hashcode, equals, toString methods are in sync ?
Come on, our time is precious, and this really totally dumb, and error prone !
But there should not be this problem to solve in the first place !
Writing all these methods manually
I used to write them manually while using emacs back in the 2000 days, let's skip these painful memories...
A little help from Eclipse
We all know how to generate all these methods using eclipse, but I had the curiosity for this post to count the number of steps to generate them:
1- Click Source / 2- click generate getter & setter / 3- click Select all / 4- click Ok
5- Click Source / 6- click generate to String / 7- click Ok
8- Click Source / 9- click generate hashcode and equals / 10- click Ok
and then, 11- I tidy up things
That’s 11 steps !
Ok, now it’s time to do some eclipse magic and bind "generate setter/getter" to a shortcut. That’s right, no big deal. But sounds like an ugly solution isn’t it?
And I insist, this problem should not exist in the first place !
So you end up with :
package com.springfuse.blog.projectlombok;
public class UsingEclipse {
private String not;
private String really;
private String fun;
public String getNot() {
return not;
}
public void setNot(String not) {
this.not = not;
}
public String getReally() {
return really;
}
public void setReally(String really) {
this.really = really;
}
public String getFun() {
return fun;
}
public void setFun(String fun) {
this.fun = fun;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((fun == null) ? 0 : fun.hashCode());
result = prime * result + ((not == null) ? 0 : not.hashCode());
result = prime * result + ((really == null) ? 0 : really.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UsingEclipse other = (UsingEclipse) obj;
if (fun == null) {
if (other.fun != null)
return false;
} else if (!fun.equals(other.fun))
return false;
if (not == null) {
if (other.not != null)
return false;
} else if (!not.equals(other.not))
return false;
if (really == null) {
if (other.really != null)
return false;
} else if (!really.equals(other.really))
return false;
return true;
}
@Override
public String toString() {
return "UsingEclipse [fun=" + fun + ", not=" + not + ", really=" + really + "]";
}
}
Basically the usual pojo suspect you see everywhere ...
Some real help from Commons-lang
Commons-lang is giving simple and effective solutions to reduce the boilerplate code with EqualsBuilder, ToStringBuilder, HashCodeBuilder.
So you have now only the getter and setter to generate with eclipse and no more need to worry about your equals/hashcode methods.
You should now have this:
package com.springfuse.blog.projectlombok;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
public class UsingCommonsLang {
private String not;
private String really;
private String fun;
public String getNot() {
return not;
}
public void setNot(String not) {
this.not = not;
}
public String getReally() {
return really;
}
public void setReally(String really) {
this.really = really;
}
public String getFun() {
return fun;
}
public void setFun(String fun) {
this.fun = fun;
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
This is better, less error prone, but we still still have so many getter/setters that we can’t stand.
Lombok comes and wins !
Now look how we do it using lombok:
package com.springfuse.blog.projectlombok;
import lombok.Data;
@Data
public class UsingProjectLombok {
private String get;
private String fun;
private String back;
}
Isn't it elegant ?
The @Data does express my intention nicely ... and completely as the code is also generated
After the shock of such a concise POJO, the next though you have is for configuration ...
Projectlombok gives you this freedom.
Please note that Lombok is a good citizen as it gives you clear warnings such as
But how does it work ?
Project lombok is a javac plugin that will use the javac 6 annotation processor.
That means that the generation of the methods is part of the compilation, and no runtime nor java agent is required !
It's almost like adding behavior with aspectj but with plain java !
Lombok does work only under javac 1.6, but if you want to target 1.5 just configure it in your pom.
But JDK 1.5 has 10 more days before it is no more supported by sun ! It is time to give this info to your boss and make the switch.
eclipse refactoring
The current version 0.8.5 does not work great in this regard, however they fixed it in the trunk.
If you do build your own, you'll be fine
git clone git://github.com/rzwitserloot/lombok.git
ant
... or wait for the next binary release !
Edit: the 0.9 release is out
Lombok generates other methods like @Cleanup, @Synchronized, @SneakyThrows
or @Logger
I am not sure what to think about these, maybe it could go too far but as the intent is clearly described via the annotation, why not...
Anyway I'll stick with the simple features for now and see how it goes.
I love this tool !
I have to say, that the combination of google collections and project lombok gave me a fresh view of what you can accomplish with java.
It feels like the gap between the language "du jour" and my plain old java has been dramatically reduced.
And you know what ?
It feels good !
2 comments:
Ca ressemble à ce que fait Spring ROO en fait, avec ses annotations comme @ToString
Post a Comment