9

We were having a discussion at my work about the use of enums in Java.

A coworker was arguing that when using enums on the server-side, whenever required we should use string to reference to it (for instance when sending data from JS to the server or when storing in the database), arguing that this is much more clearer for the developer and also arguing that it would fail fast in case of typos.

I always used integers to identify enums in these cases, because it would be immutable identifiers and would not have case and typo problems (even though if a dev made the mistake of using the value 2 instead of 1, it would not fail fast).

Being very analytic about these arguments, I would say that using strings is better, but I get a strange feeling about it (as if it was not a good approach).

Is there any best practice regarding this discussion that could guide me?

Edit: Whenever it is possible, we use the enum itself, so all our Java code uses the Enum. By "reference to an enum" I mean: referencing the value in the enum when exchanging data from JavaScript to the server or storing data in the database

  • 1
    What is a "reference to an enum" for you? Normal use within source code? Serialization for storing in a data base? Expression to use in user documentation? Expression to use in technical documentation? The answer will be quite different for all of those. – Kilian Foth Dec 16 '14 at 12:49
  • I've edited the question and I hope it is clearer now: by "reference to an enum" I mean referencing the value when exchanging data from JavaScript to the Server or the other way around or storing a value in the database – JSBach Dec 16 '14 at 12:57
  • In the javascript API I'd certainly use strings. In the DB both have their advantages. Some databases have built in enum support. – CodesInChaos Dec 16 '14 at 13:05
13

Good question. The use of enum in Java is primarily meant to handle information that is somewhat categorical in nature. The classic example being using enum to handle the four types of suits that a card could have. It provides all the performance advantage of using an integer and it is also clear in your program.

So outside of Java, why wouldn't you continue using an integer? Perhaps you don't have enum types outside Java, though that doesn't mean you can't continue using integer for performance purposes, right? Yes, that's completely true, though consider what happens when you add a new enum value. If you don't add it to the end, all the other enum values after the new value will be increased by one. Well we'll just specify the number so it can't change or we'll always add it to the end. Are you confident that your fellow coworkers will always do right by that? Meh? Probably? Hopefully? Maybe you're not 100% on that. Keep that in mind for a second.

Your boss tells you that there's a mess at the client using your software after the last update. Now all entities X act like they were assigned enum value Y even if they were really assigned Z. You check the repository and yes, someone added a new enum value and didn't follow your guidelines as you asked them to. Now you have the added complication that on the database it is written 4, when it really should be 3, excluding records that have been inserted prior to the update which really are 4. What enum value pertains to 4 anyway? Isn't it Y? You can't remember. You need to check the program to verify. Simply put, it's a mess.

If instead, your database wrote "HEARTS", "DIAMONDS", "SPADES", "CLUBS", you've lost little in terms of space and gained so much. It's true we're talking about a minor performance hit, but you really should not be accessing the database that often to make a difference. As for space, leave that to the systems administrators (not. your. problem.).

If you've made a simple program that is easy to make changes to, you've done yourself a favor in the long run, trust me. This aspect of it is no different in my humble opinion.

  • 2
    Good points, but you're forgetting about the case where someone decides to change the name of one of the enum entities (HEARTS to Heart or something in your example) and suddenly everything breaks again. – Scott Whitlock Dec 16 '14 at 14:01
  • 1
    @ScottWhitlock Not if you account for that, though they could decide to rename it entirely. They could accidentally delete the database and delete the project too, but we can't account for every possible incident here. – Neil Dec 16 '14 at 14:09
  • 5
    @Neil - true but we're trying to play the odds here. I'm not familiar with Java enums, but in C#, I explicitly set the values for enums if the values need to have meaning outside the program (such as in a database) (e.g. Hearts = 1, Diamonds = 2, etc.). Since that's not the default way to use an enum, it should give a later editor pause. Plus a comment noting where else these are used is handy. – Scott Whitlock Dec 16 '14 at 17:34
  • 1
    @ScottWhitlock That is definitely the better way to go about it in order to avoid such problems. Though supposing you did that, you still see 1, 2, 3, 4 on the database or serialized in some file. Not ideal from a maintenance standpoint any way you slice it. – Neil Dec 17 '14 at 8:50
  • 2
    If I may add, if the enum is serialized as string and someone changes the name of an enum, during deserialization the error will be during the parsing. If the enum is int and someone changes the definition, the error will be further down the line, during processing, which will be harder to diagnose. CC @ScottWhitlock. – Endy Tjahjono Jun 25 '18 at 5:49
1

I agree with Neil's answer, but just an addition:

In java enums are Objects, so they can have fields and methods. So you can give each enum some manualy specified value and when referencing it for outside work, use that value instead.

It will survive both adding/removing/reordering and changing name of enum instance. But you will have to write serialization/deserialization logic for enum fields instead of using automagic available in many tools. (Its easy, but its aditional work).

And you must keep those values unique manually (but that's same in C style enums), and you can write test to check that.

  • Yes, we went down this path, but we are using hibernate and we had to add some extra code to be able to parse the value to/from the database and it seemed kind of strange, so we decided to use the .STRING relationship and go with the enum name. – JSBach Dec 18 '14 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.