Archive for August, 2013

August 20, 2013

Mutable variable capture in anonymous Java classes

by Jay Jonas

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 at

August 5, 2013

Running javah tool from Eclipse

by Jay Jonas

The javah produces C header files and C source files from a Java class that are needed to implement native methods. The javah -jni is used to generate a C header file containing the function prototype for the native method implementation.

The javah can be configured as an external tool like this: click Run |External Tools |External Tools Configurations. This will invoke External Tools Configurations wizard.

Select Program Type and create a new launch configuration.

For Location, click on Browse File System and browse to the path of javah tool (typically <java_home>\bin).

For Working Directory, click on Browse Workspace and select upto project output directory (directory where class files reside – typically ${workspace_loc:/your.jni.project/bin})

Various options of javah command may be added here which is then followed by ${java_type_name} workspace variable which returns the fully qualified Java type name of the primary type in the selected resource.

The argument list instructs the tool to keep the generated header file in a directory named jni under the project folder. If -d option is not specified, the header files will be stored in bin folder itself.

"${project_loc}${system_property:file.separator}jni" ${java_type_name}
External Tools Configuration

External Tools Configuration

// That’s all, folks!