Skip to main content

Writing enums before Tiger

Posted by mister__m on December 10, 2003 at 10:46 PM PST

One thing I've been missing in Java is support for enums. Some of you might be asking: but what is a enum and why should I care about them? A enum is, in a simple way, a class with a limited domain. For example, a class representing the seasons we have during the year - although climate seems crazy these days, anyway, but that's a different story - is a enum. Another example would be a class that represents gender, as it only has two values, male and female (though, again, some might argue it is not that simple :-D).

Enums for J2SE 1.5 are being defined by JSR-201. I recommend you read the draft spec when you have the chance, but I'll cite the relevant points as needed. First, let's take a look at the main features both - my implementation and the future J2SDK 1.5 one - share, as specified by the draft spec at the JCP site:

  1. Compile-time type safety
  2. Performance comparable to int constants.
  3. Type system provides a namespace for each enum type, so you don't have to prefix each constant name.
  4. Typesafe constants aren't compiled into clients, so you can add, reorder or even remove constants without the need to recompile clients. (If you remove a constant that a client is using, you'll fail fast with an informative error message.)
  5. Printed values are informative. (Which would you rather see in a stack trace: "Indigo" or "6?")
  6. Enum constants can be used in collections (e.g., as HashMap keys).
  7. You can add arbitrary fields and methods to an enum class.
  8. An enum type can be made to implement arbitrary interfaces.

How is it possible to achieve these things now? By using the Enum class provided by my open-source project, reusable-components! Here is a code snippet:

import net.java.dev.reusablecomponents.lang.Enum;

public final class Gender extends Enum implements MyInterface {
   public static final Gender MALE = new Gender("Male");
   public static final Gender FEMALE = new Gender("Female");

   private Gender(String name) {
      super(name);
   }
}

In this example, MyInterface is a simple marker interface that is implemented just to show you it is possible to do so. :-D The code doesn't look that complicated, but it gives you all those things and also these additional features quoted from the JCP spec:

All enum classes have high-quality toString, hashCode, and equals methods. All 
are Serializable, Comparable and effectively final. None are Cloneable.

Arbitrary fields may be added to enum classes, and to individual enum constants.

To be exact, you have to make your Enum subclasses final. If you subclass an Enum subclass, it simply won't work. However, the greatest feature these Enum subclasses have is that their instances may be compared using the == operator. Even if you deserialize an instance, you still can use the operator instead of calling equals. Isn't that great? I think so, but I'm not neutral enough to give opinions about code I wrote. :-D

Surely, there are some differences between my Enum and the one provided by the JSR-201. I hope to explain most of them here, but to be sure you understand all the differences, read the spec linked above and browse the most recent version of my Enum implementation.

While the J2SE 1.5 enum is intended to give you comparability, it limits the way you naturally compare your instances by making compareTo final. reusable-components' implementation doesn't make the method final, giving you freedom to override it as needed. Besides that, JSR-201 is going to give as an enum facility, which is something much bigger than just a class: we will have a new keyword, new syntax and more compiler "gambiarras", as we would say in Portuguese: the compiler is going to make lots of things to your source code to make it look like a regular class. To give you an idea of what the J2SE 1.5 enum probably is going to be like, here is the original example modified:

public enum Gender implements MyInterface {
   male, female
}

Although it is by far cleaner than the code I showed above, it requires special compiler features and most IDEs won't support it now.

Maybe you could be thinking: but why I need to use a superclass if I can write an enum implementation on without one? Well, you would have to rewrite things you need, such as serialization and == support, for example. The fact you have a base class also helps to organize your code and to evolve it as you find bugs.

Now that I gave you a general idea of what net.java.dev.reusablecomponents.lang.Enum can do, it is time to mention a few more things. There are methods that allow you to get all the instances for a given subclass and to get an instance given its class and its identifying name. Those methods are especially useful if you are using enums as part of a web application: you need to populate combos and to get the selected instance to do your job.

If you are interested enough, I recommend you check the code. You can ask questions and leave your comments below. reusable-components is intended to give you more than that, though; in the next few weeks, I expect to commit some validators for user input and also a cool image generator for use in forms to make sure users aren't frauding your application. Join the project if you want to help. And stay tuned.

Related Topics >>