Some reader favorites:
EJB fundamentals and session beans
Create a scrollable virtual desktop in Swing
Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API
Because Java lacks a proper C/C++ enumeration (enum) feature, Java programmers have opted to define simple sets of primitive values:
public class Colors
{
public static final int GREEN = 0;
public static final int RED = 1;
...
}
This is not particularly typesafe, but it works. You can easily copy and serialize these constants, and then use them for
fast switch lookups and so on. In fact, this is how Java language designers originally advised Java programmers to handle Java's lack
of an enumeration feature (see "The Java Language Environment" whitepaper).
The typesafe Java enum concept basically replaces the set of primitive constants above with a set of static final object references encapsulated in a class that (possibly) restricts further instantiation. A basic example would be:
public final class Enum
{
public static final Enum TRUE = new Enum ();
public static final Enum FALSE = new Enum ();
private Enum () {}
} // end of class
Because the set of instances is restricted by the private constructor and Enum class being final, we can assume that Enum.TRUE and Enum.FALSE are the only instances of the Enum class. Thus, we can use the identity comparison (==) operator instead of the equals() method when comparing enum values. The cost of using the == operator equates to directly comparing pointer values in C/C++. Great, right? We have both type and range safety for enum
values while keeping value comparisons efficient.
Alas, the simple Enum class above lacks a few features. One missing feature is that we cannot pass instances of our Enum class as an argument to an RMI (remote method invocation) or EJB (Enterprise JavaBeans) method. To do that, we must mark
the class Serializable:
public final class Enum implements java.io.Serializable
{
public static final Enum TRUE = new Enum ();
public static final Enum FALSE = new Enum ();
private Enum () {}
} // end of class
The above has a subtle trap, as shown here:
ByteArrayOutputStream bout = new ByteArrayOutputStream ();
ObjectOutputStream out = new ObjectOutputStream (bout);
Enum e1 = Enum.TRUE;
out.writeObject (e1);
out.flush ();
ByteArrayInputStream bin = new ByteArrayInputStream (bout.toByteArray ());
ObjectInputStream in = new ObjectInputStream (bin);
Enum e2 = (Enum) in.readObject ();
System.out.println ((e2 == Enum.TRUE || e2 == Enum.FALSE));
This code will print out false, indicating that e2 is neither Enum.TRUE nor Enum.FALSE. This happens because deserializing an object creates a new object without regard to the class's constructors -- the instantiation
protection that we thought we got from making the Enum constructor private doesn't affect deserialization.
This could lead to unexpected results in runtime environments like an EJB container, especially since most EJB containers support optimization options to disable the serialization marshalling of method arguments for beans deployed in the same JVM. Your code's runtime behavior will then depend on this option's setting -- not a very comforting thought, is it?
Free Download - 5 Minute Product Review. When slow equals Off: Manage the complexity of Web applications - Symphoniq
![]()
Free Download - 5 Minute Product Review. Realize the benefits of real user monitoring in less than an hour. - Symphoniq