Search code examples
javastringconstantsfinal-class

What is the best practice to handle related constant strings in Java?


Let us assume that I have to handle several constant strings that are closely related, for example types of messages ("ID1", "ID2", "ID3"). Currently I use a final class that only has public static final definitions:

public final class MessageType {
   public static final String ID1 = "ID1";
   public static final String ID2 = "ID2";
   public static final String ID3 = "ID3";
}

In the various classes I access the strings as MessageType.ID<X>. Is this the best way to handle this scenario or the best practice is different? Thanks.


Solution

  • This approach has one big drawback: There's no decent way to transform a String such as "ID1" back to MessageType.ID1.

    The common approach here is to use an enum:

    public enum MessageType {
      ID1,
      ID2,
      ID3
    }
    

    Their String representation is MessageType.ID1.name(). You can transform the name back to a constant by iterating over MessageType.values().

    This has the limitation that the constants need to be valid regarding the java syntax. Enums are basically a list of instances of that enum class. Writing down the constant names is essentially a call to a constructor. That means you can assign values to each instance:

    public enum MessageType {
      ID1("ID 1"), //calls the constructor
      ID2("something else with spaces");
    
      private final String text; //field
    
      MessageType(String t) { //the constructor
        this.text = t;
      }
    
      //and the lookup:
      static MessageType getByText(String text) {
        for(MessageType t:values()) {
          if(t.text.equals(text)) {
            return t;
          }
        }
        return null;
      }
    
      public String getText() {
        return text;
      }
    }
    

    You can now access these longer Strings using MessageType.ID2.text. Calling MessageType.getByText("ID 1") will return MessageType.ID1.