Is it possible to limit the valid enum values that a method can accept.
Say, for example, I have an enum like this:
public enum WEEKDAY {
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY;
}
And say I have a method that only should accept an inner set of those values:
//Here dayOfWeek should only be Monday - Friday.
public void setWorkDayAlarm(WEEKDAY dayOfWeek) {
}
I know you can obviously switch on the valid values, and in the default case not do anything. But is there a way (or a pattern) to define in the interface of the method, that it only accepts a certain subset of valid enums in Java (5+)?
Enums definitely have limits, with the primary (hard) limit around 32K values. They are subject to Java class maximums, both of the 'constant pool' (64K entries) and -- in some compiler versions -- to a method size limit (64K bytecode) on the static initializer.
The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.
Enum Fields The enum constructor must be private . You cannot use public or protected constructors for a Java enum . If you do not specify an access modifier the enum constructor it will be implicitly private .
Yes, you can define abstract methods in an enum declaration if and only if all enum values have custom class bodies with implementations of those methods (i.e. no concrete enum value may be lacking an implementation).
I don't know that the type system can help you here. What about something like this?
public enum DayOfWeek {
SUNDAY(false), MONDAY(true), TUESDAY(true), WEDNESDAY(true),
THURSDAY(true), FRIDAY(true), SATURDAY(false);
private final boolean isWeekday;
private DayOfWeek(boolean isWeekday) {
this.isWeekday = isWeekday;
}
public boolean isWeekday() {
return isWeekday;
}
}
Then check the argument:
public void setWorkDayAlarm(DayOfWeek dayOfWeek) {
if (!dayOfWeek.isWeekday())
throw new IllegalArgumentException("Need weekday, got " + dayOfWeek);
// ...
}
The language itself provides no way to build subsets of an enum. That would defeat the purpose of an enum in the first place - to have a defined set of values for a given domain.
What you can do: Define another appropriate enum for that domain and provide reasonable cross-mappings. To get the idea:
public enum WORKDAY {
MONDAY(WEEKDAY.MONDAY),
TUESDAY(WEEKDAY.TUESDAY),
WEDNESDAY(WEEKDAY.WEDNESDAY),
THURSDAY(WEEKDAY.THURSDAY),
FRIDAY(WEEKDAY.FRIDAY);
final public WEEKDAY weekday;
WORKDAY(WEEKDAY wd){
this.weekday = wd;
}
static WORKDAY convertWeekday(WEEKDAY weekday){
// in real live use a static EnumMap
for(WORKDAY workday: values())
if( workday.weekday == weekday )
return workday;
return null; // or an exception
}
}
public void setWorkDayAlarm(WORKDAY workDay){ ... }
The good thing: The caller of the conversion method must deal with these values which are not mappable. Your method stays clean.
Since the method you provided there is public, it is acceptable to throw an IllegalArgumentException if a caller gives it an invalid value. For a private method, you could have a debug assertion fail.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With