JAU: Java Annotation Based Utilities
I am glad to announce the first stable beta ;-) of the JAU library (http://code.google.com/p/jau/). Version 0.6 implements the following methods using annotations (and works for POJOs):
- equals
- hashCode
- toString
- compareTo
- copy/clone
- toMap/fromMap (this one creates a java.util.Map with object properties as entries)
Here is a sample use case:
import com.googlecode.jau.*;
@JAUEquals
@JAUHashCode
@JAUToString
@JAUCompare
@JAUCopy
@JAUToMap
public class UserData implements Comparable, Cloneable {
private String firstName;
private String secondName;
private Date birthDate;
private String login;
@JAUEquals // not really necessary. All fields are included by default
private String[] rights = new String[] {"view"};
@JAUEquals(include=false)
@JAUHashCode(include=false)
@JAUCompare(include=false)
private javax.swing.event.EventListenerList listeners = new javax.swing.event.EventListenerList();
// constructor omitted
public boolean equals(Object obj) {
return JAU.equals(this, obj);
}
public int hashCode() {
return JAU.hashCode(this);
}
public String toString() {
return JAU.toString(this);
}
public int compareTo(Object obj) {
return JAU.compare(this, obj);
}
public UserData clone() throws CloneNotSupportedException {
UserData r = (UserData) super.clone(this);
JAU.copy(this, r);
return r;
}
}
For example, the output for
JAU.toString(new String[][] {{"a", "b"}, {"1", "2"}})
would be
java.lang.String[][java.lang.String["a", "b"], java.lang.String["1", "2"]]
- Login or register to post comments
- 2862 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)










Comments
Ronald Miura replied on Wed, 2009/01/28 - 6:50am
Now this is a clear misuse of annotations...
And, what are the annotations supposed to do in your example, since you end up calling the JAU utility class anyway?
Arek Stryjski replied on Wed, 2009/01/28 - 7:06am
Ronald is right, using annotations to dynamically change a class is misuse from annotations specification point of view, but I don't have a problem with it.
But I have many questions:
In case you are not inserting the implementation:
(I apology for such a stupid question, I know nobody will put annotations just for code decoration.)
Tim replied on Wed, 2009/01/28 - 7:12am
in response to: ronaldtm
Misuse!? The use case is very similar to EJB 3.
JAU.equals for example compares 2 objects and only use fields for comparison annotated with @JAUEquals. Other methods work in similar fashion.
Calling JAU.equals and similar methods is only necessary to avoid bytecode modification or code generation yet to override the Object.equals() method.
Tim replied on Wed, 2009/01/28 - 10:18am
in response to: areks
It doesn't change the class dynamically. There is no bytecode modification.
@JAUEquals(include=false)
private EventListenerList listeners;
aldobrucale replied on Wed, 2009/01/28 - 9:00am
If I understand correctly, annotating the fields lets one choose which fields should be included in the equals/hashCode/etc. methods?
Tim replied on Wed, 2009/01/28 - 10:13am
in response to: aldobrucale
jkilgrow replied on Wed, 2009/01/28 - 6:58pm
joecoder replied on Wed, 2009/01/28 - 8:08pm
aruggles replied on Wed, 2009/01/28 - 9:39pm
I thought the point of Annotating classes was to move the configuration from external files like XML to the code that it affects. What this seems to do is move the code from one location to another. I don't see the benefit/advantage.
Peter Thomas replied on Thu, 2009/01/29 - 1:04am
Heh. This kind of misuse was predicted three years ago in this blog post (not mine):
http://uri.jteam.nl/?p=15
Tim replied on Thu, 2009/01/29 - 3:42am
in response to: joecoder
to joecoder:
thanks. I have updated the code so it is more clear.
Tim replied on Thu, 2009/01/29 - 3:43am
in response to: aruggles
to aruggles:
see the advantages in my reply to jkilgrow
Tim replied on Thu, 2009/01/29 - 3:49am
in response to: pt93903
Yardena replied on Thu, 2009/01/29 - 4:56am
Tim replied on Thu, 2009/01/29 - 5:16am
in response to: yardena
You are right Yardena,
performance is an issue I want to address before 1.0 is ready. JAU will always be slower than hand-written methods (but You can write them in places where performance is important and use with JAU) because it uses reflection. On the other side nothing in the API prevents on-the-fly bytecode generation in the future versions.
peterhuber replied on Thu, 2009/01/29 - 1:21pm
in response to: yardena
I remember that there was a guy proposing a similar approach to equals and hashCode about half a year ago. His post led to heated discussion about performance of his solution which he had tested and had to admit was between very bad and horrible...I know that equals and hashCode play a big role in the world of java (though I again and again find "experienced" java programmers who simply don't care...until they get the bill) and as such I want to have them perform well in terms of speed. The annotated solution will only work well with byte-code instrumentation, otherwise it has to use reflection...even if cached it's bad because then I pay memory for speed.
And I really, really, really don't see why I should not use eclipse source-generate-equals function which generates me all I need as if taken out of the book 'effective java'? Yes, yes I have to do it whenever I want to add a field or remove one, but I like the 'do it myself and have the control' rather than the 'I guess it might work with that library'.
So probably someone will find the old thread with the guy that failed before...
--
Found it myself: http://java.dzone.com/tips/refactor-safe-tostringbuilder
Tim replied on Thu, 2009/01/29 - 3:29pm
in response to: peterhuber
to peterhuber:
thank you for the pointer /trying to be genuine was harder than it seemed.../.
You always trade something for something: memory for speed, usability for implementation time etc. JAU seems to trade ease of use/simplicity for performance and maybe flexibility.
I'll publish some numbers on the project site until 1.0 is released. What slowdown would You find acceptable?
BTW: the GridGain guy got 14/3 votes and me only 7/6. The times got tougher :-).
peterhuber replied on Fri, 2009/01/30 - 3:04am
Tim - I really like the idea of making things easier. So I think I like your idea of making the tedious work of implementing equals/hashCode easier.
But you know that hibernate and other ORMs use these methods alot. They all have different levels of caches and do optimizations, for instance "don't write back an unchanged entity". Such an optimization relies on equals…If your convenient approach is only a small percentage slower than hand coded (with the help of eclipse) I would use the hand coded stuff for really 'big' projects (big in terms of page hits, say amazon).
If you solve the Problem of performance with byte code instrumentation than I guess I would build up some sort of fear like "what code is running there?". It's instrumented by hibernate, any arbitrary dependency injection framework like that with the season in its name...what was the name of this all-absorbing thingy...and last but not least with your stuff. Hopefully the debugger has any chance to resolve this mess if you have any problems.
As you might have guessed from my postings, I'm more the sceptic type of guy...just try to convince me/us with a sustainable solution.