sle*_*ske 26 java enums design-patterns language-design
在JDK1.5之前的Java中,"Typesafe Enum"模式是实现只能获取有限数量值的类型的常用方法:
public class Suit {
private final String name;
public static final Suit CLUBS =new Suit("clubs");
public static final Suit DIAMONDS =new Suit("diamonds");
public static final Suit HEARTS =new Suit("hearts");
public static final Suit SPADES =new Suit("spades");
private Suit(String name){
this.name =name;
}
public String toString(){
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
(参见例如Bloch的Effective Java的第21项).
现在在JDK1.5 +中,"官方"方式显然是使用enum:
public enum Suit {
CLUBS("clubs"), DIAMONDS("diamonds"), HEARTS("hearts"), SPADES("spades");
private final String name;
private Suit(String name) {
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
显然,语法更好一些,更简洁(不需要显式定义值的字段,适合toString()提供),但到目前为止enum看起来非常类似于Typesafe Enum模式.
我所知道的其他差异:
values()方法switch()(并且编译器甚至会检查您是否忘记了值)但这一切看起来只不过是语法糖,甚至还有一些限制(例如enum总是继承java.lang.Enum,也不能是子类).
是否有其他更基本的好处,enum使用Typesafe Enum模式无法实现?
当然,其他人会在这里提到很多优点作为答案.最重要的是,你可以写enums非常快,他们做了很多的事情一样实现Serializable,Comparable,equals(),toString(),hashCode(),等你没在你的枚举包括.
但我可以告诉你一个严重的缺点的enum(IMO).您不仅无法随意对它们进行子类化,而且还无法为它们配备通用参数.当你写这个:
// A model class for SQL data types and their mapping to Java types
public class DataType<T> {
private final String name;
private final Class<T> type;
public static final DataType<Integer> INT = new DataType<Integer>("int", Integer.class);
public static final DataType<Integer> INT4 = new DataType<Integer>("int4", Integer.class);
public static final DataType<Integer> INTEGER = new DataType<Integer>("integer", Integer.class);
public static final DataType<Long> BIGINT = new DataType<Long>("bigint", Long.class);
private DataType(String name, Class<T> type){
this.name = name;
this.type = type;
}
// Returns T. I find this often very useful!
public T parse(String string) throws Exception {
// [...]
}
}
class Utility {
// Enums equipped with generic types...
public static <T> T doStuff(DataType<T> type) {
return ...
}
}
Run Code Online (Sandbox Code Playgroud)
这是枚举不可能的:
// This can't be done
public enum DataType<T> {
// Neither can this...
INT<Integer>("int", Integer.class),
INT4<Integer>("int4", Integer.class),
// [...]
}
Run Code Online (Sandbox Code Playgroud)