今天我浏览了这个网站上的一些问题,我发现一个枚举被用于单例模式,据称线程安全的好处,这种解决方案。
我从来没用过枚举,而且我已经用Java编程好几年了。显然,他们改变了很多。现在他们甚至在自己内部完全支持OOP。
为什么我应该在日常编程中使用enum ?
今天我浏览了这个网站上的一些问题,我发现一个枚举被用于单例模式,据称线程安全的好处,这种解决方案。
我从来没用过枚举,而且我已经用Java编程好几年了。显然,他们改变了很多。现在他们甚至在自己内部完全支持OOP。
为什么我应该在日常编程中使用enum ?
当前回答
枚举以自记录的方式枚举一组固定的值。 它们使您的代码更显式,也更不容易出错。
为什么不使用String,或int,而不是Enum常量?
编译器不允许错别字,也不允许出值的修正 设置,因为枚举本身就是类型。后果: 你不需要写一个先决条件(或手册)来确保你的论点在有效范围内。 类型不变式是免费的。 枚举可以有行为,就像任何其他类一样。 无论如何,您可能需要类似数量的内存来使用string(这取决于Enum的复杂性)。
此外,Enum的每个实例都是一个类,您可以为其定义单独的行为。
另外,它们在创建实例时(当枚举被加载时)确保线程安全,这在简化单例模式中有很好的应用。
这篇博客说明了它的一些应用,比如解析器的状态机。
其他回答
当一个变量(特别是一个方法参数)只能从一组可能的值中选取一个时,您应该始终使用枚举。例如类型常量(合约状态:“永久”,“临时”,“学徒”)或标志(“立即执行”,“延迟执行”)。
如果使用枚举而不是整数(或字符串代码),则增加了编译时检查,避免了传入无效常量的错误,并且记录了哪些值是可以合法使用的。
顺便说一句,过度使用枚举可能意味着你的方法做了太多的事情(通常有几个单独的方法会更好,而不是一个方法有几个标记来修改它所做的事情),但如果你必须使用标记或类型代码,枚举是最好的选择。
举个例子,哪个更好?
/** Counts number of foobangs.
* @param type Type of foobangs to count. Can be 1=green foobangs,
* 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
* @return number of foobangs of type
*/
public int countFoobangs(int type)
与
/** Types of foobangs. */
public enum FB_TYPE {
GREEN, WRINKLED, SWEET,
/** special type for all types combined */
ALL;
}
/** Counts number of foobangs.
* @param type Type of foobangs to count
* @return number of foobangs of type
*/
public int countFoobangs(FB_TYPE type)
方法调用如下:
int sweetFoobangCount = countFoobangs(3);
然后就变成:
int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);
在第二个例子中,很明显哪些类型是允许的,文档和实现不能不同步,编译器可以强制执行这一点。 另外,无效调用
int sweetFoobangCount = countFoobangs(99);
已经不可能了。
不管别人怎么说…在我曾经工作过的一个旧项目中,实体(独立应用程序)之间的大量通信使用代表一个小集合的整数。用静态方法将set声明为enum很有用,可以从value中获取enum object,反之亦然。代码看起来更干净,开关案例可用性和更容易写入日志。
enum ProtocolType {
TCP_IP (1, "Transmission Control Protocol"),
IP (2, "Internet Protocol"),
UDP (3, "User Datagram Protocol");
public int code;
public String name;
private ProtocolType(int code, String name) {
this.code = code;
this.name = name;
}
public static ProtocolType fromInt(int code) {
switch(code) {
case 1:
return TCP_IP;
case 2:
return IP;
case 3:
return UDP;
}
// we had some exception handling for this
// as the contract for these was between 2 independent applications
// liable to change between versions (mostly adding new stuff)
// but keeping it simple here.
return null;
}
}
使用ProtocolType.fromInt(2)从接收的值(例如1,2)创建enum对象 使用myEnumObj.name写入日志
希望这能有所帮助。
从Java文档-
您应该在任何时候使用枚举类型 需要表示一个固定的集合 常量。包括自然enum 比如我们太阳系中的行星 你知道的系统和数据集 编译时所有可能的值 时间——例如,a上的选项 菜单、命令行标志等等。
一个常见的例子是用枚举类型替换一个类,用一组私有静态final int常量(常量数量合理)。基本上,如果你认为你在编译时知道“something”的所有可能值,你可以将其表示为枚举类型。比起带有常量的类,枚举提供了可读性和灵活性。
枚举类型几乎没有其他优点。它们总是特定枚举类的一个实例(因此出现了使用枚举作为单例的概念)。另一个优点是可以在switch-case语句中使用枚举作为类型。你也可以在枚举上使用toString()将它们打印为可读的字符串。
枚举以自记录的方式枚举一组固定的值。 它们使您的代码更显式,也更不容易出错。
为什么不使用String,或int,而不是Enum常量?
编译器不允许错别字,也不允许出值的修正 设置,因为枚举本身就是类型。后果: 你不需要写一个先决条件(或手册)来确保你的论点在有效范围内。 类型不变式是免费的。 枚举可以有行为,就像任何其他类一样。 无论如何,您可能需要类似数量的内存来使用string(这取决于Enum的复杂性)。
此外,Enum的每个实例都是一个类,您可以为其定义单独的行为。
另外,它们在创建实例时(当枚举被加载时)确保线程安全,这在简化单例模式中有很好的应用。
这篇博客说明了它的一些应用,比如解析器的状态机。
我会使用枚举作为有用的映射工具,避免使用多个if-else 前提是实现了一些方法。
public enum Mapping {
ONE("1"),
TWO("2");
private String label;
private Mapping(String label){
this.label = label;
}
public static Mapping by(String label) {
for(Mapping m: values() {
if(m.label.equals(label)) return m;
}
return null;
}
}
因此by(String label)方法允许您通过非枚举获取枚举值。此外,还可以创建两个枚举之间的映射。还可以尝试“1对多”或“多对多”,除了“一对一”的默认关系
最后,enum是一个Java类。你可以在里面有main方法,这在需要马上对参数做一些映射操作时很有用。