今天我浏览了这个网站上的一些问题,我发现一个枚举被用于单例模式,据称线程安全的好处,这种解决方案。
我从来没用过枚举,而且我已经用Java编程好几年了。显然,他们改变了很多。现在他们甚至在自己内部完全支持OOP。
为什么我应该在日常编程中使用enum ?
今天我浏览了这个网站上的一些问题,我发现一个枚举被用于单例模式,据称线程安全的好处,这种解决方案。
我从来没用过枚举,而且我已经用Java编程好几年了。显然,他们改变了很多。现在他们甚至在自己内部完全支持OOP。
为什么我应该在日常编程中使用enum ?
当前回答
枚举就像类。与类一样,它也有方法和属性。
不同阶级的区别是: 1. 枚举常量是public, static, final。 2. 枚举不能用于创建对象,也不能扩展其他类。但是它可以实现接口。
其他回答
知道枚举就像其他具有常量字段和私有构造函数的类一样是有用的。
例如,
public enum Weekday
{
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
编译器按如下方式编译它;
class Weekday extends Enum
{
public static final Weekday MONDAY = new Weekday( "MONDAY", 0 );
public static final Weekday TUESDAY = new Weekday( "TUESDAY ", 1 );
public static final Weekday WEDNESDAY= new Weekday( "WEDNESDAY", 2 );
public static final Weekday THURSDAY= new Weekday( "THURSDAY", 3 );
public static final Weekday FRIDAY= new Weekday( "FRIDAY", 4 );
public static final Weekday SATURDAY= new Weekday( "SATURDAY", 5 );
public static final Weekday SUNDAY= new Weekday( "SUNDAY", 6 );
private Weekday( String s, int i )
{
super( s, i );
}
// other methods...
}
除了前面提到的用例,我经常发现枚举对于实现策略模式很有用,遵循一些基本的面向对象原则:
将代码放在数据所在的位置(即在枚举本身中——或者通常在枚举常量中,这可能会覆盖方法)。 实现一个(或更多)接口,以便不将客户端代码绑定到枚举(它应该只提供一组默认实现)。
最简单的例子是一组Comparator实现:
enum StringComparator implements Comparator<String> {
NATURAL {
@Override
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
},
REVERSE {
@Override
public int compare(String s1, String s2) {
return NATURAL.compare(s2, s1);
}
},
LENGTH {
@Override
public int compare(String s1, String s2) {
return new Integer(s1.length()).compareTo(s2.length());
}
};
}
这种“模式”可以在更复杂的场景中使用,广泛使用枚举附带的所有优点:遍历实例,依赖于它们的隐式顺序,根据实例名称检索实例,为特定上下文提供正确实例的静态方法等等。你仍然把这些都隐藏在接口后面,这样你的代码就可以在不需要修改的情况下使用自定义实现,以防你想要一些“默认选项”中不可用的东西。
我曾看到这种方法成功地应用于时间粒度(每天、每周等)概念的建模,其中所有逻辑都封装在枚举中(为给定的时间范围选择正确的粒度,将特定行为绑定到每个粒度作为常量方法等)。而且,服务层所看到的粒度只是一个接口。
而不是做一堆const int声明
您可以将它们都分组在一个enum中
所以它们都是由它们所属的共同群体组织起来的
枚举以自记录的方式枚举一组固定的值。 它们使您的代码更显式,也更不容易出错。
为什么不使用String,或int,而不是Enum常量?
编译器不允许错别字,也不允许出值的修正 设置,因为枚举本身就是类型。后果: 你不需要写一个先决条件(或手册)来确保你的论点在有效范围内。 类型不变式是免费的。 枚举可以有行为,就像任何其他类一样。 无论如何,您可能需要类似数量的内存来使用string(这取决于Enum的复杂性)。
此外,Enum的每个实例都是一个类,您可以为其定义单独的行为。
另外,它们在创建实例时(当枚举被加载时)确保线程安全,这在简化单例模式中有很好的应用。
这篇博客说明了它的一些应用,比如解析器的状态机。
在我看来,你到目前为止的所有答案都是正确的,但根据我的经验,我想用几句话来表达:
如果希望编译器检查标识符值的有效性,请使用枚举。
否则,您可以像往常一样使用字符串(可能您为应用程序定义了一些“约定”),并且您将非常灵活……但是你不能在你的字符串上获得100%的安全,你只能在运行时意识到它们。