The Java compiler requires local variables of enclosing contexts referenced in anonymous classes (so-called captured variables) to be final. What if the anonymous class wants to alter the value of the variable, i.e. requires the variable to be mutable? This post shows different ways how to achieve that.
Mutability with an array
The most common way to solve this problem is to put the variable into an array of length one, make the array final and capture the array:
<br /><%%KEEPWHITESPACE%%> JButton button = new JButton("Press me!");<br /><%%KEEPWHITESPACE%%> final String[] message = new String[]{"Never been pressed"};<br /><%%KEEPWHITESPACE%%> button.addActionListener(new ActionListener() {<br /><br /><%%KEEPWHITESPACE%%> @Override<br /><%%KEEPWHITESPACE%%> public void actionPerformed(ActionEvent e) {<br /><%%KEEPWHITESPACE%%> message[0] = "Pressed";<br /><%%KEEPWHITESPACE%%> }<br /><br /><%%KEEPWHITESPACE%%> });<br />The value is stored in the first slot of the array. The reference to the array is final but its element stays mutable.
While this approach works fine, it looks strange and will certainly raise questions for developers in your team which have never seen this construct before.
Mutability with a holder
The better way to make the message mutable is to put it into a holder class
<br /><%%KEEPWHITESPACE%%> class Holder {<br /><%%KEEPWHITESPACE%%> private T value;<br /><br /><%%KEEPWHITESPACE%%> Holder(T value) {<br /><%%KEEPWHITESPACE%%> setValue(value);<br /><%%KEEPWHITESPACE%%> }<br /><br /><%%KEEPWHITESPACE%%> T getValue() {<br /><%%KEEPWHITESPACE%%> return value;<br /><%%KEEPWHITESPACE%%> }<br /><br /><%%KEEPWHITESPACE%%> void setValue(T value) {<br /><%%KEEPWHITESPACE%%> this.value = value;<br /><%%KEEPWHITESPACE%%> }<br /><%%KEEPWHITESPACE%%> }<br />and pass the holder into the inner class:
<br /><%%KEEPWHITESPACE%%> JButton button = new JButton("Press me!");<br /><%%KEEPWHITESPACE%%> final Holder mutableMessage = new Holder("Never been pressed");<br /><%%KEEPWHITESPACE%%> button.addActionListener(new ActionListener() {<br /><br /><%%KEEPWHITESPACE%%> @Override<br /><%%KEEPWHITESPACE%%> public void actionPerformed(ActionEvent e) {<br /><%%KEEPWHITESPACE%%> mutableMessage.setValue("Pressed");<br /><%%KEEPWHITESPACE%%> }<br /><br /><%%KEEPWHITESPACE%%> });<br />This solution states more clearly why the message has been wrapped. If the holder is implemented as a generic utility class, this solution is not more verbose than the one with the array. In case you don’t want to implement the Holder class yourself, you can also reuse the MutableObject from Apache Commons or the Holder from Google Guava. One could argue that the solution with the array is faster (creating an array is usually faster than instantiating a class), but in most cases the performance loss will be negligible.
// from Tillmann Seidel at eclipsesource.com/blogs
Eclipse Task Tags Meaning
by Jay JonasTODO
, along withFIXME
andXXX
, is known in Eclipse as a task tag, and is indexed by the IDE to let you find the spots marked with those tags easily. You can edit such tags in the Eclipse Preferences -> Java -> Compiler -> Task Tags.This is the list for default Eclipse Task Tags and their meaning:
TODO
Comments that mark something for later work, later revision or at least later reconsideration. ODO comments should be considered a very useful technique, although like all good things on Earth, there’s certainly potential for abuse.
FIXME
A standard put in comments near a piece of code that is broken and needs work.
XXX
A marker that attention is needed. Commonly used in program comments to indicate areas that are kluged up or need to be. Some hackers like `XXX’ to the notional heavy-porn movie rating. Use it to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken.
ZZZ /* This tag is mine! ; ) */
Sometimes I like to use this marker for a stuff that was commented as deprecated just to remind me what happened there. However, when I’m sure, I delete it along with the code.
Posted in Eclipse, Notes, Quick Tips | Leave a Comment »