Getting to know Java’s Enum

I don’t know why, but the Enum class’ usefulness has always eluded me. Early attempts just didn’t work out, and I just found ways around using it. Recently, I am writing a program that needs to have a certain status be toggled between a known, fixed list of values-with a default value if nothing else matches. This real world project accelerated my learning how to use Enum effectively-much more so that the urgency to simply learn more about the language (i.e. no practical application of said knowledge).

I also wanted this magical class to determine for itself which value from the aforementioned list the thing that had the Enum in the first place should be. In other words, I wanted the method to do the determination to be inside the Enum class itself. I didn’t know if this was possible, but as I went over all the other ways to accomplish this, any other solution was too costly and inelegant.

To give you an idea of what I am trying to accomplish, consider this Test.java:

EventType is the Enum class. Pay close attention to the line:

etY = etX.getEventType(sEvent);

I am feeding the method a String (sEvent), and expecting a EventType object back. In other words, a method inside the EventType class itself is going to determine the value that etY should have. This means that mt Test.class objects will have automatically determined their Enum type without any messy additional code in the business logic. This was my objective, as there is no better place for this than inside the EventType class.  I can adjust the list of possibilities, and all the parsing logic, in one logical, intuitive place.

So lets take a look at EventType.java:

I really like this. Not only was I able to have all my Enum constants (Windows, UNIX, etc.), but I have the magical getEventType method. In this example, I wanted any part of a supplied String having “test” in it (case-sensitive) to cause the returned EventType to be “Windows”. All else, “Default”. I just added get/set_id for good form, and later applications I have in mind.

So lets run Test.java, which if you’ll remember also lists all EventType values at the end of it’s run:

Now those of you more knowledgeable than me would be asking why I didn’t go for Enum’s valueOf(), as in:

…and having getEventType() return a String instead of an EnumType object. I thought about this, and it definitely works with the same lines of code. In the calling code, I would need the extra step of converting the String to it’s equivalent EventType, was my logic, so I stayed with the simpler “return an object” strategy.

So I’ll next put it to a little load test:

Which is a MATCH, yields:

real    0m11.482s

Changing line #6 to:

String sEvent = “this is just a Test!”;

Which is NOT a match, yields a surprising:

real    0m15.018s

That is a difference of 3.536 seconds, or 31% slower when the Regex does NOT match.

I didn’t expect any difference there, as both examples were with getEventType() returning an EventType object. Now I’ll change EventType.getEventType() to return a string, and use the “valueOf” assignment in the LoadTest class:

Notice the Regex will be a match (lower case “test“). Before we run this half of the test, and for reference, this is what the EventType Enum class looks like when it is returning a String:

(At the end, I’ll show the output of a diff on the compiled source to show just how close the 2 versions really are.)

So now let’s run LoadTest.class WITH a regex match. Remember from above that when we returned an EventType object, the results were:

Match:        real    0m11.482s

No match: real    0m15.018s

Wow! The first run (matches) is:

real    0m11.852s (0.370 seconds faster!)

And with NO match:

real    0m14.909s (0.109 seconds slower)

I did not expect these results. All things considered, the times are the same. The decision is still obvious to me, as I want my code to be readable-especially if the performance is the same.

Overall, 10,000,000 iterations of this program were performed in about 12 seconds. This means each iteration took 1.2 microseconds on a Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz with 4GB RAM. AND that counts initial loading.

Summary

I would rather have:

etY = etX.getEventType(sEvent);

…instead of:

etY = EventType.valueOf(etX.getEventType(sEvent));

Wouldn’t you?

Decompile Diff

If you want to see the difference in these 2 approaches, here is the diff of the decompiles of both approaches:

Not what I expected! So hopefully this has shown you:

  1. How to use Enum creatively.
  2. How to use an Enum method to determine an Enum’s value for you.
  3. The performance differences (or lack!) between direct object assignment and indirect valueOf Enum value assignment.
pat
:)

Leave a Reply

Your email address will not be published. Required fields are marked *