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.
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
.