Java – Is Public Final OK in Constant Enum Fields

java

When I make enums that hold some fields, like my Settings enum, I like to make them public final to avoid lots of ( and ) keystrokes:

public enum Settings {
  SETTING_TEST("bool_setting1", false),
  USERNAME("user_name", "me")
  ;

  public final String name;
  public final Object default_val;
  Setnames(String n, Object d) {
    name = n;
    default_val = d;    
  }
}

This enum is then applied to look up (or set the default) settings in some hashmap (encapsulated in more sophistiated class). This design allows to control the setting names over the whole project (since enum names can be refactored, unlike strings).

My teacher warned me about this design though, and there are some answers suggesting that you can regret designing your project with public final without encapsulation.

I'm not only asking for rules and conventions but also your experience (the help center doesn't say anything negative about asking for opinions, so I do so). While I'd gladly even expand the question on other languages that support features in question, I'm not sure this wouldn't make the question too broad – which is why I think we should stick to Java only.

Edit:

The SE GUI asks me to explain how is my question different from the one I linked to. Other people already pointed out in comments the difference, but let's repeat it:

Most answers on the other question point out problems not applicable to enums. Often we use getXXX encapsulation to allow classes extend our class properly. But we cannot extend from enum. Generally, despite similar syntax, enums are substantially different from classes and interfaces.

Best Answer

My personal opinion is that public final is generally fine everywhere, not just on enums.

In my book, there are only two reasons for not using public final, and these are:

  • Allowing for future changes which might require altering the nature of the fields while maintaining binary compatibility with external code. (A getter would allow this.)

  • Typing 'get' and letting autocomplete show me everything that I can read from an object without having to scroll up and down in the autocomplete list to see if besides getter methods there are also any public final fields that I can read (whose names presumably do not start with get.)

As for the points made by the answer that you linked to, none of them are applicable to enums.

So, even if you don't agree that public final is generally fine everywhere, still, at least for enums, it is really-really fine.