[Java] Enumerations: My New Friend!

Introduction

Most programmers have little libraries of code that they use often that they have written. I have some myself for Java. One of these classes that I have written is called DirectoryAssembler. To put it simply, I pass it an argument stating where I want data stored and the name of a folder to append to that directory. I get back a string that is the absolute path to where that folder can exist. DirectoryAssembler takes care of finding out what the System OS is, figuring out where the “program data” folder is; That kind of thing. Of course I’m a beginning programmer so most of my code is bloated and horrible. Well today’s article is on my discovery of Enumerations and how they changed my code significantly; hopefully for the better.

Note: I will try to explain some terms. However, a history in programming will help out understanding everything here.

Enumerations – What are they?

To put it simply, an Enumeration is a list of constants. In C/C++, you can have the following:

enum shipcost { FIGHTER = 25, FIGHTER_BOMBER, CRUISER = 50 };

The above might be the cost of ships. Then through out your code you just use the enum instead of the literal int throughout. This is useful because if you later to decide to change the cost of a Fighter to say, 30, you can just change the enumeration value instead of going through and replacing every single occurrence of 25. I could have just declared a const int instead of an enumeration, but the enum is a list of items and is useful for switches and order.

 

Enumerations in Java

Enumerations in Java have similarities to enum’s in C/C++. However, the Java Enum’s are far more powerful. In C/C++ you can only assign ints to enums. In Java, you can assign any type or object to an Enumeration. Enumerations can also be put in their own file and given their own methods. Lastly, you can use the toString() method of an Enum to print it’s literal value name. Here is an example of an Enumeration for OSTypes that I used for my DirectoryAssembler.

package org.silicateillusion.io;

public enum OSType
{
    UNSUPPORTED_OS("Unknown", OSType.OS_UNKNOWN),

    WINDOWS_XP("Windows XP", OSType.OS_WINDOWS),

    WINDOWS_VISTA("Windows Vista", OSType.OS_WINDOWS),

    WINDOWS_7("Windows 7", OSType.OS_WINDOWS),

    WINDOWS_SERVER_2K3("Windows 2003", OSType.OS_WINDOWS),

    WINDOWS_SERVER_2K8("Windows 2008", OSType.OS_WINDOWS);

    public static final int OS_UNKNOWN = 0;

    public static final int OS_WINDOWS = 1;

    private final String sOSName;

    private final int iOSType;

    OSType(String osName, int type)
    {
        sOSName = osName;

        iOSType = type;
    }

    public String getOSName()
    {
        return sOSName;
    }

    public int getType()
    {
        return iOSType;
    }
}

 

Lines 5 through 15 are the actual Enum’s. Each enumeration takes a String obj and an Int listed later in the file. I listed OS_UNKNOWN and OS_WINDOWS as public static final int because they didn’t fit inside of the enumeration but were still needed as constants.

Lines 25 through 30 is the Constructor for the Enumeration Class. In java Enumeration classes, the constructor is implicitly public. In fact, whenever I try to put public infront of it Eclipse threw an error at me. Lines 32 through 41 are Getters for the data contained within each Enumeration.

If you can understand all of that, You’re doing good. Otherwise There isn’t much more I can say. Now onto what that changed within the main DirectoryAssembler Class. One of the most notable changes was to the OSType function, which determines the OS that the program is currently running on. Here is what it originally looked like.

public OSType osType()
{
    String sName = System.getProperty("os.name");

    if ("Windows XP".equals(sName))
    {
        return OSType.WINDOWS_XP;
    }
    else if ("Windows Vista".equals(sName))
    {
        return OSType.WINDOWS_VISTA;
    }
    else if ("Windows 7".equals(sName))
    {
        return OSType.WINDOWS_7;
    }
    else if ("Windows 2003".equals(sName))
    {
        return OSType.WINDOWS_SERVER_2K3;
    }
    else if ("Windows 2008".equals(sName))
    {
        return OSType.WINDOWS_SERVER_2K8;
    }
    else
    {
        return OSType.UNSUPPORTED_OS;
    }
}

 

So the above is filled with a bunch of icky if-else if statements doing string compares for the OS Name. Well since I have moved the OS Name to the Enumeration, my code was changed and shortened to this:

 

public OSType osType()
{
    String sName = System.getProperty("os.name");

    for (OSType type : OSType.values())
    {
        if (type.getOSName().equals(sName))
        {
            return type;
        }
    }

    return OSType.UNSUPPORTED_OS;
}

Much Much more agreeable don’t you think? I think so as well. But that wasn’t the only change. I had a method that would check to see if the os isWindows(). Well needless to say, I had one big if statement with every single Windows OS and the ‘or’ operator (||). That was quiet messy as well before it was transformed into this:

 

public boolean isWindows()
{
    if (OSType.OS_WINDOWS == eOSType.getType())
    {
        return true;
    }
    else
    {
        return false;
    }
}

 

As you can see, the above is more elegant than one large IF statement.

Conclusion

Well, I hope you’ve learned about how powerful/useful enumerations in Java can be. I was certainly surprised and delighted by the changes in my code cause of this. I’m certainly going to do more with enumerations now. The one thing to remember through out all of this is whether or not an enumeration is right for what you are doing. For me, the above code was simplified and written more elegantly because of an Enum. For that I am thankfull. However, not all constants necessarily need an Enum.