It's an interesting question, how one handles variables that is the same for all objects of the class and does not change during runtime, and at the same time is allowed to be configurable between executions. Since the first two prerequisites dictate that the variable should be static and final (e.g. a constant), the third really doesn't fit in, meaning that there will be no pretty way to achieve all three (reflection is needed, or one has to drop either the static or the final constraint).
Since there is no pretty solution to the way things are modeled now, I think the wisest would be to take a step back and rethink the placement of the variable: Is it necessary to keep this logic in the enum itself? What is different when changing the value of the constant, the enum itself, or something else? In what cases does this constant have to change it's value?
In your example it might be that different countries have different thresholds for what is regarded as adult, or that the threshold changes, then maybe a small service that determines which PersonType
a Person
has is the right way to go.
@Service
public class PersonTypeService {
@Value("${threshold.for.adulthood}")
private int thresholdForAdulthood;
public PersonType determinePersonType(final Person person) {
if (person.getAge() >= thresholdForAdulthood) {
return PersonType.ADULT;
}
return PersonType.CHILD;
}
}
In general I like to let enums only answer the "what", and leave the "how" and the "why" to domain classes and services. In the example, all the enum needs to know is the values it provides a person, why it should provide a certain value, or how it is determined, does not belong in the enum.
This is a my opinion, but put utility code into enum is not a good pratice; `enum`s are designed to contains values, not to have code you can refactor in a lot of other ways – Luca Basso Ricci Jul 04 '14 at 09:57