今天我浏览了这个网站上的一些问题,我发现一个枚举被用于单例模式,据称线程安全的好处,这种解决方案。
我从来没用过枚举,而且我已经用Java编程好几年了。显然,他们改变了很多。现在他们甚至在自己内部完全支持OOP。
为什么我应该在日常编程中使用enum ?
今天我浏览了这个网站上的一些问题,我发现一个枚举被用于单例模式,据称线程安全的好处,这种解决方案。
我从来没用过枚举,而且我已经用Java编程好几年了。显然,他们改变了很多。现在他们甚至在自己内部完全支持OOP。
为什么我应该在日常编程中使用enum ?
当前回答
现在我为什么要用,为什么要用 在日常编程中枚举?
您可以使用Enum来表示较小的固定常数集或内部类模式,同时增加可读性。此外,在方法参数中使用enum时,可以加强一定的刚性。它们提供了一种有趣的可能性,可以将信息传递给一个构造函数,就像在Oracle网站上的Planets示例中那样,而且,正如您所发现的,还允许以一种简单的方式创建一个单例模式。
例:Locale.setDefault(Locale.US)读起来比Locale.setDefault(1)更好,并强制使用IDE中显示的固定值集。分隔符,而不是所有整数。
其他回答
除了前面提到的用例,我经常发现枚举对于实现策略模式很有用,遵循一些基本的面向对象原则:
将代码放在数据所在的位置(即在枚举本身中——或者通常在枚举常量中,这可能会覆盖方法)。 实现一个(或更多)接口,以便不将客户端代码绑定到枚举(它应该只提供一组默认实现)。
最简单的例子是一组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());
}
};
}
这种“模式”可以在更复杂的场景中使用,广泛使用枚举附带的所有优点:遍历实例,依赖于它们的隐式顺序,根据实例名称检索实例,为特定上下文提供正确实例的静态方法等等。你仍然把这些都隐藏在接口后面,这样你的代码就可以在不需要修改的情况下使用自定义实现,以防你想要一些“默认选项”中不可用的东西。
我曾看到这种方法成功地应用于时间粒度(每天、每周等)概念的建模,其中所有逻辑都封装在枚举中(为给定的时间范围选择正确的粒度,将特定行为绑定到每个粒度作为常量方法等)。而且,服务层所看到的粒度只是一个接口。
不管别人怎么说…在我曾经工作过的一个旧项目中,实体(独立应用程序)之间的大量通信使用代表一个小集合的整数。用静态方法将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写入日志
希望这能有所帮助。
使用枚举类型安全,这是一个语言特性,所以你通常会得到:
编译器支持(立即查看类型问题) ide中的工具支持(在切换情况下自动补全,缺失情况,强制默认,…) 在某些情况下,枚举的性能也很好(EnumSet,类型安全的替代传统的基于int的“位标志”)。
枚举可以有方法、构造函数,甚至可以在枚举中使用枚举,并将枚举与接口结合使用。
可以将枚举看作是替换一组定义良好的int常量的类型(Java从C/ c++“继承”了int常量),在某些情况下还可以替换位标志。
《Effective Java 2nd Edition》一书中有一整章是关于它们的,并且有更多的细节。也可以参考Stack Overflow的文章。
Java允许将变量限制为只有几个预定义值之一——换句话说,枚举列表中的一个值。 使用枚举可以帮助减少代码中的bug。 下面是一个类外部枚举的例子:
enums coffeesize{BIG , HUGE , OVERWHELMING };
//This semicolon is optional.
这限制了咖啡的大小:大的,巨大的,或压倒性的变量。
Enum继承Object类和抽象类Enum的所有方法。所以你可以使用它的方法来反射、多线程、序列化、可比性等等。如果你只是声明一个静态常量而不是Enum,你就不能。除此之外,Enum的值也可以传递给DAO层。
下面是要演示的示例程序。
public enum State {
Start("1"),
Wait("1"),
Notify("2"),
NotifyAll("3"),
Run("4"),
SystemInatilize("5"),
VendorInatilize("6"),
test,
FrameworkInatilize("7");
public static State getState(String value) {
return State.Wait;
}
private String value;
State test;
private State(String value) {
this.value = value;
}
private State() {
}
public String getValue() {
return value;
}
public void setCurrentState(State currentState) {
test = currentState;
}
public boolean isNotify() {
return this.equals(Notify);
}
}
public class EnumTest {
State test;
public void setCurrentState(State currentState) {
test = currentState;
}
public State getCurrentState() {
return test;
}
public static void main(String[] args) {
System.out.println(State.test);
System.out.println(State.FrameworkInatilize);
EnumTest test=new EnumTest();
test.setCurrentState(State.Notify);
test. stateSwitch();
}
public void stateSwitch() {
switch (getCurrentState()) {
case Notify:
System.out.println("Notify");
System.out.println(test.isNotify());
break;
default:
break;
}
}
}