枚举
枚举类型是强类型的,把一些运行期的参数检查放到了编译期。枚举更加安全,提高了代码的可读性。不仅可以保证单例,且比较时候可以用 ”==” 来替换 equals 。
案例:
public enum Color {
RED(255,0,0,"赤"),
ORANGE(255,128,0,"橙"),
YELLOW(255,255,0,"黄"),
GREEN(0,255,0,"绿"),
CYAN(0,255,255,"青"),
BLUE(0,0,255,"蓝"),
PURPLE(128,0,255,"紫");
private final int red;
private final int green;
private final int blue;
private final String description;
Color(int red, int green, int blue,String description) {
this.red = red;
this.green = green;
this.blue = blue;
this.description = description;
}
@Override
public String toString() {
return name()+"("+red+","+green+","+green+")->" + description;
}
}
public class TestColor {
public static void main(String[] args) {
Color green = Color.GREEN;
System.out.println(green);
}
}
常用方法:
public final String name():返回此枚举常量的名称,与其枚举声明中声明的完全相同。
public final int ordinal():返回此枚举常数的序数(其枚举声明中的位置,其中初始常数的序数为零)。
public static <T extends Enum> T valueOf(类 enumType,String name): 返回具有指定名称的指定枚举类型的枚举常量。 该名称必须与用于声明此类型的枚举常量的标识符完全一致。 (不允许使用外来空白字符。)
使用枚举会占用更多的空间在javac编译完成后会产生多个.class文件比一般的的多文件也更大
静态常量:
使用静态常量来代替枚举
案例:
public class Season {
public static final int SPRING=1;
public static final int SUMMER=2;
public static final int ATUMN=3;
public static final int WINTER=4;
}
public class CompareStaticConstantTest {
public static void main(String[] args) {
staticConstant(1);
}
public static void staticConstant(int seaon){
switch (seaon){
case Season.SPRING:
System.out.println("SPRING do...");
break;
case Season.SUMMER:
System.out.println("SUMMER do...");
break;
case Season.ATUMN:
System.out.println("ATUMN do...");
break;
case Season.WINTER:
System.out.println("WINTER do...");
break;
}
}
}
这样代码明显简洁很多,但是静态常量就没有缺点吗
1.可以看出,使用静态常量是无法存入更多的属性值
使用枚举可以存储code,name,color,feel等信息,而且并没有限制,但是使用静态常量就只能存储code和name两个值
2.还有就是在使用过程中,无法传入的参数进行限制
使用枚举时,传入的参数为为Season的枚举类型的数据,这也就限定了参数的范围,降低了代码出错的可能性
但是使用静态常量的话,传入的只是一个整型数据,如果使用时传递了一个1-4之外的数,程序时不会报错的,但是在运行时就会出错
总结:
枚举提高了代码的安全性和可读性,但是也占用了更多的内存空间
静态变量占用内存更小,但是可存储的数据有限,而且对于代码的可读性也不如枚举
枚举更适合于资源要求不严格或枚举种类不多且枚举需要存储多种属性时使用
静态常量适用于资源要求严格,且存储数据少的情况使用
枚举方便维护,静态常量方便使用。
- 枚举型可以直接与数据库打交道,我通常使用varchar类型存储,对应的是枚举的常量名。(数据库中好像也有枚举类型,不过也没用过)
-
switch语句支持枚举型,当switch使用int、String类型时,由于值的不稳定性往往会有越界的现象,对于这个的处理往往只能通过if条件筛选以及default模块来处理。而使用枚举型后,在编译期间限定类型,不允许发生越界的情况
-
当你使用常量类时,往往得通过equals去判断两者是否相等,使用枚举的话由于常量值地址唯一,可以用==直接对比,性能会有提高
-
常量类编译时,是直接把常量的值编译到类的二进制代码里,常量的值在升级中变化后,需要重新编译引用常量的类,因为里面存的是旧值。枚举类编译时,没有把常量值编译到代码里,即使常量的值发生变化,也不会影响引用常量的类。
- 枚举类编译后默认为final class,不允许继承可防止被子类修改。常量类可被继承修改、增加字段等,容易导致父类的不兼容。
结合案例:
public enum Gender {
//枚举值都是大写字母
//枚举值1, 枚举值2, ...
MAN, WOMEN;
}
public class Person {
private String name;
//private String sex;
private Gender sex; //性别使用枚举表示,可以规范取值
public Person(String name, Gender sex) {
this.name = name;
this.sex = sex;
}
}
public class Test {
public static void main(String[] args) {
Person p1 = new Person("张三", Gender.MAN);
Person p2 = new Person("李四", Gender.WOMEN);
}
}
反编译:
//季节
public enum Season {
SPRING , //春
SUMMER, //夏
AUTUMN, //秋
WINTER; //冬
}
/*
反编译代码
public final class Season extends Enum{
public static final Season SPRING = new Season("SPRING", 0);
public static final Season SUMMER = new Season("SUMMER", 1);
public static final Season AUTUMN = new Season("AUTUMN", 2);
public static final Season WINTER = new Season("WINTER", 3);
private Season(String s, int i){
super(s, i);
}
}
结论:
枚举类编译后本质是final修饰的java类,并且继承了java.lang.Enum类。
枚举类的构造方法都是private修饰的,所以枚举类无法在外部创建对象。
每个枚举值都是该类的对象,并且都是public static final修饰的。
枚举本质是一个java类,所以枚举中可以有成员变量、成员方法、构造方法等成分