限制Enum潜在值的方法

时间:2011-10-14 18:39:45

标签: java oop design-patterns enums

是否可以限制方法可以接受的有效枚举值。

比如说,我有一个这样的枚举:

public enum WEEKDAY {
    SUNDAY,
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY;
}

并说我有一个方法只接受这些值的内部集合:

//Here dayOfWeek should only be Monday - Friday.
public void setWorkDayAlarm(WEEKDAY dayOfWeek) {
}

我知道你显然可以打开有效值,在默认情况下不做任何事情。但是在方法的接口中是否有一种方法(或模式),它只接受Java(5 +)中有效枚举的某个子集?

4 个答案:

答案 0 :(得分:7)

我不知道类型系统可以在这里帮助你。这样的事情怎么样?

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;
    }
}

然后检查参数:

public void setWorkDayAlarm(DayOfWeek dayOfWeek) {
    if (!dayOfWeek.isWeekday())
        throw new IllegalArgumentException("Need weekday, got " + dayOfWeek);

    // ...
}

答案 1 :(得分:3)

语言本身无法构建枚举的子集。这首先会破坏枚举的目的 - 为给定的域定义一组值。

可以做什么:为该域定义另一个适当的枚举并提供合理的交叉映射。得到这个想法:

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){ ... }

好处:转换方法的调用者必须处理这些不可映射的值。你的方法保持清洁。

答案 2 :(得分:1)

由于您提供的方法是公开的,因此如果调用者为其提供无效值,则可以抛出IllegalArgumentException。对于私有方法,您可能会遇到调试断言失败。

答案 3 :(得分:0)

要通过方法签名(类型系统,如@pholser所说)在Plain Old Java中无法实现。有一些框架,例如CDI,或者替代编程风格,例如Design By Contract,可以做你想要的。

相关问题