On our current project we are mapping some magic numbers from database (sigh, I know) to java enums like so:
public interface WithCode {
Integer getCode();
}
public enum Role implements WithCode {
OWNER(1),
ADMIN(2),
USER(3);
@Getter Integer code;
Role(Integer code) {
this.code = code;
}
}
We have handful of these, so we created an utility that finds appropriate enum by ID like so:
public interface EnumLookuper {
static <T extends Enum<T> & WithCode> T ofCode(int code, Class<T> enumType) {
return Arrays.stream(enumType.getEnumConstants())
.filter(value -> Objects.equals(value.getCode(), code))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(String.format("Unknown %s with code %d", enumType.getName(), code)));
}
}
Our algorithm is perhaps a bit too aggressive - it fails on unknown values. Some other team members have added new magic numbers to DB and our project started to throw bunch of exceptions.
Now, I'd like to add UNKNOWN
value to each enum (we have tens of those) and I was thinking of doing it a bit more generically, so we'd change the exception throwing line to something like:
.orElseGet(() -> defaultEnumValue())
Enforcing the defaults with an interface wouldn't work really, as we'd need to provide default value for each enum member. Any ideas of introducing elegant fallback/unknown values for each enum?
EDIT
Using a custom "unknown value interface" would force me to implement unknown value per enum member, for example:
interface UnknownValueProvider<T> {
T unknown();
}
public enum Role implements WithCode, UnknownValueProvider<Role> {
OWNER(1) {
public Role unknown() {
return ...;
}
}