I've seen this pattern a few times - it can make sense if the strings represent something found outside Java code and outside your control, such as constants used in a database (e.g. possible values of a field), and the established values of these constants do not match Java naming conventions for enums. This also assumes the list of allowed values does not change often, and if it does change, you need to release a new version of the enum to handle the changes. Which can be a pain. But, it's nice to be able to use the enum within Java code, especially if there is other behavior you want to attach. If this matches your situation reasonably well, enums with alternate String names can make sense. And yes, there's some repeated code in there, because enums can't extend anything other than the Enum class, and Java doesn't have mix-ins, so you can't really inherit any other behavior. I don't think there are any good ways to reduce the amount of code here. It's not too bad though.
I would note that many of us regard it as Wrong™ to use a name like CONSTANT_VALUE for a field that is not a compile-time constant, and is not static, but is simply an immutable instance field. That's misleading to those of us used to standard naming conventions. Also I would prefer not to override toString(), which is changing the expected behavior for an enum, but instead add a new method, like getName() of getDbValue(). (The name of such a method can also be useful in telling people what you need this alternate String for.) But that's more of a personal preference, as the toString() contract of Enum is flexible.
Campbell Ritchie wrote:Why? If you need String constants, use String constants.
I think the key question here is whether these form distinct value sets. If you only want a way to refer to a String value in code to avoid magic string, then a String constant is all you need. If you're going to have variables that can only take a value out of one of these sets, then an enum is a good idea (I think).
For example, will there ever be variables of type CacheConstants? Or will we just be using it to refer to CacheConstants.MEM_CACHE and the like?