NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed. (sponsored)
In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.
Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.
Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
Serialization is a handy and powerful aspect of Java. Being able to persist objects onto disk and read them later is one of the most under-used features of Java I think. In the base cases, serialization can 'just work'. However, as more complicated object formats and design patterns are adopted, the likelihood that 'transparent' object serialization will 'just work' becomes less and less likely. One case where serialization needs a little help is when dealing with a controlled set of instances - such as singletons and enumerations.
Whenever a singleton is serializable, it's important to ensure that the singleton instance is used. This is done through the
readResolve
method. For instance, a singleton may look like this:
In the above example, there is only one way to get an instance of
MySingleton
- that is to use the
getInstance()
method. Unfortunately, this code becomes 'broken' simply by adding one interface implementation:
Now through the serializable tools, someone can write a singleton instance to disk, and then read it back up, effectively getting a new instance. Even though the constructor is private, the serializable tools have special access to create instances of a class regardless. Serialization has a special hook it uses - a private method on the class being instantiated called
readResolve()
- which is meant to supply a 'hook' for a class developer to ensure that they have a say in what object is returned by serialization. Oddly enough,
readResolve()
is not static, but is instead invoked on the new instance just created by the serialization. We'll get into that in a minute - for now, here is how our
readResolve()
method works with our singleton:
publicfinalclass MySingleton {
private MySingleton() { }
privatestaticfinal MySingleton INSTANCE = new MySingleton();
publicstatic MySingleton getInstance() { return INSTANCE; }
private Object readResolve() throws ObjectStreamException {
// instead of the object we're on,
// return the class variable INSTANCE
return INSTANCE;
}
}
So far so good. Things get a little complicated when dealing with more than one instance however. To explain this, I'll show this using a type-safe enumeration. Keep in mind that Java 5's
enum
type automatically handles this
readResolve
case for you. Here is a nice little enumeration:
publicfinalclass Sides {
privateint value;
private Sides(int newVal) { value = newVal; }
privatestaticfinalint LEFT_VALUE = 1;
privatestaticfinalint RIGHT_VALUE = 2;
privatestaticfinalint TOP_VALUE = 3;
privatestaticfinalint BOTTOM_VALUE = 4;
publicstaticfinal LEFT = new Sides(LEFT_VALUE);
publicstaticfinal RIGHT = new Sides(RIGHT_VALUE);
publicstaticfinal TOP = new Sides(TOP_VALUE);
publicstaticfinal BOTTOM = new Sides(BOTTOM_VALUE);
}
Now, implementing serialization, the key to determining which instance to return is in inspecting what value is set on the object itself:
publicfinalclass Sides implements Serializable {
privateint value;
private Sides(int newVal) { value = newVal; }
privatestaticfinalint LEFT_VALUE = 1;
privatestaticfinalint RIGHT_VALUE = 2;
privatestaticfinalint TOP_VALUE = 3;
privatestaticfinalint BOTTOM_VALUE = 4;
publicstaticfinal LEFT = new Sides(LEFT_VALUE);
publicstaticfinal RIGHT = new Sides(RIGHT_VALUE);
publicstaticfinal TOP = new Sides(TOP_VALUE);
publicstaticfinal BOTTOM = new Sides(BOTTOM_VALUE);
private Object readResolve() throws ObjectStreamException {
// Switch on this instance's value to figure out which class variable
// this is meant to match
switch(value) {
case LEFT_VALUE: return LEFT;
case RIGHT_VALUE: return RIGHT;
case TOP_VALUE: return TOP;
case BOTTOM_VALUE: return BOTTOM;
}
returnnull;
}
}
Serialization: Understand 'readResolve'
At 12:58 AM on Feb 28, 2005, R.J. Lorimer wrote:
Fresh Jobs for Developers Post a job opportunity
Serialization is a handy and powerful aspect of Java. Being able to persist objects onto disk and read them later is one of the most under-used features of Java I think. In the base cases, serialization can 'just work'. However, as more complicated object formats and design patterns are adopted, the likelihood that 'transparent' object serialization will 'just work' becomes less and less likely. One case where serialization needs a little help is when dealing with a controlled set of instances - such as singletons and enumerations.
Whenever a singleton is serializable, it's important to ensure that the singleton instance is used. This is done through the
readResolvemethod. For instance, a singleton may look like this:public final class MySingleton { private MySingleton() { } private static final MySingleton INSTANCE = new MySingleton(); public static MySingleton getInstance() { return INSTANCE; } }In the above example, there is only one way to get an instance of
MySingleton- that is to use thegetInstance()method. Unfortunately, this code becomes 'broken' simply by adding one interface implementation:public final class MySingleton implements Serializable { //...Now through the serializable tools, someone can write a singleton instance to disk, and then read it back up, effectively getting a new instance. Even though the constructor is private, the serializable tools have special access to create instances of a class regardless. Serialization has a special hook it uses - a private method on the class being instantiated called
readResolve()- which is meant to supply a 'hook' for a class developer to ensure that they have a say in what object is returned by serialization. Oddly enough,readResolve()is not static, but is instead invoked on the new instance just created by the serialization. We'll get into that in a minute - for now, here is how ourreadResolve()method works with our singleton:public final class MySingleton { private MySingleton() { } private static final MySingleton INSTANCE = new MySingleton(); public static MySingleton getInstance() { return INSTANCE; } private Object readResolve() throws ObjectStreamException { // instead of the object we're on, // return the class variable INSTANCE return INSTANCE; } }So far so good. Things get a little complicated when dealing with more than one instance however. To explain this, I'll show this using a type-safe enumeration. Keep in mind that Java 5's
enumtype automatically handles thisreadResolvecase for you. Here is a nice little enumeration:public final class Sides { private int value; private Sides(int newVal) { value = newVal; } private static final int LEFT_VALUE = 1; private static final int RIGHT_VALUE = 2; private static final int TOP_VALUE = 3; private static final int BOTTOM_VALUE = 4; public static final LEFT = new Sides(LEFT_VALUE); public static final RIGHT = new Sides(RIGHT_VALUE); public static final TOP = new Sides(TOP_VALUE); public static final BOTTOM = new Sides(BOTTOM_VALUE); }Now, implementing serialization, the key to determining which instance to return is in inspecting what value is set on the object itself:
public final class Sides implements Serializable { private int value; private Sides(int newVal) { value = newVal; } private static final int LEFT_VALUE = 1; private static final int RIGHT_VALUE = 2; private static final int TOP_VALUE = 3; private static final int BOTTOM_VALUE = 4; public static final LEFT = new Sides(LEFT_VALUE); public static final RIGHT = new Sides(RIGHT_VALUE); public static final TOP = new Sides(TOP_VALUE); public static final BOTTOM = new Sides(BOTTOM_VALUE); private Object readResolve() throws ObjectStreamException { // Switch on this instance's value to figure out which class variable // this is meant to match switch(value) { case LEFT_VALUE: return LEFT; case RIGHT_VALUE: return RIGHT; case TOP_VALUE: return TOP; case BOTTOM_VALUE: return BOTTOM; } return null; } }0 replies so far (
Post your own)