看了点东西,发现对java枚举不是很了解,然后就找找看看记记了。
为什么要用枚举呢?枚举再jdk1.5之前是没有的,1.5之后java才支持枚举。为什么要用枚举呢?
如果一个变量只有几种可能的值,这时候我们可以用int、String或者其他类型的变量来表示,虽然可以这样做但是,这样我们无法保证
使用时候的值一定是我们约定好几个值,这样就难免产生不必要的麻烦,而枚举就能避免这样的错误,枚举类型其实就是将变量的值一一列举出来,
变量的值只限于列举出来的值的范围内,一旦定义了枚举类型变量,那么该变量只能定义范围内的值,这样一来我们在使用时就不用再考虑太多了。
再java中声明枚举用enum关键字,事实上我们的定义的枚举都是集成自java.lang.Enum类,由于java是但继承的所有我们定义的枚举不能再去
继承别的类。
public enum Color { Red,White,Bule }
以上就是简答的枚举,声明了自己的枚举类型Color,它有且只有三个类型 Red,White,Bule
再使用时就可以很方便的使用了
class TestEnum { public static void main(String[] args) { Color color = Color.Red; System.out.println(color); System.out.println("-----------------"); for(Color color2:Color.values()) { System.err.println(color2); } } }
枚举有个很方便的方法values,此方法可以去java.lang.annotation.ElementType中找,方法给我们提供了很放的便利枚举的方法。
jdk上是这样说的
Returns an array containing the constants of this enum type, in the order they are declared. This method may be used to
iterate over the constants as follows:
for(ElementType c : ElementType.values()) System.out.println(c);
当然这是不enum的values方法,但他们都是一样的,我也没找到再何处声明的这values,再网上找到了这样的说法:
“values()方法,你应该理解为类型enum的特有方法,在这里,enum是声明一个类型,它与Enum是不同的概念,就像我们知道int声明一个类型,而Integer是他的外覆类,对于int,有个方法+,-,乘除,但在Integer中我们并没有+,-乘除的形式的方法,在这里也是一样的道理
enum作为新的类型,你应该把他理解成int,double,String同样的类型”,我觉得这就是答案了。
Enum还有一个oridinal的方法,该方法返回枚举值在枚举类中的顺序,这个顺序根据枚举值声明的顺序而定。
Enum的compareTo()方法,比较此枚举与指定对象的顺序。在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。
枚举常量只能与相同枚举类型的其他枚举常量进行比较。该方法实现的自然顺序就是声明常量的顺序
* 定义枚举类型时,本质上就是再定义一个类别,只不过很多细节由编译器帮忙完成了,
* 所以某些程度上,enum关键字的作用就像class interface 一样
* 当使用enum定义枚举类型时,实质上定义出来的类型是继承自java.lang.Enum类型的
* 而每个枚举的成员其实就是定义的枚举类型的一个实例,它们都被预设为 final,所以无法改变它们
* 它们也是static 成员,所以可以通过类型名称直接使用它们,当然最重要的,它们都是public的
*换句话说,当定义了一个枚举类型后,再编译时刻就能确定该枚举类型有几个实例,分别是什么,
*早运行期间我们无法在使用该枚举类型创建新的实例了,这些实例再编译期间就已经完全确定下来了
枚举中也可以有构造方法、有成员变量、有方法总的来说枚举跟普通的java类几乎一样区别有以下几点:
枚举类的构造函数只能使用private访问修饰符,如果省略了其构造器的访问控制符,则默认使用private修饰。这样可以保证外部代码无法新构造枚举类的实例。
枚举类的所有实例必须在枚举类中显式列出,否则这个枚举类将永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰,无需程序员显式添加。
要注意的是变量和方法定义必须放在所有枚举值定义的后面,否则编译器会给出一个错误。
package com.tai.enums; public enum Coin { penny("hello"),nickel("world"),dime("welcome"),quarter("hello world"); // public static final Coin pennys("111"); private String value; public String getValue() { return value; } Coin(String value) { this.value = value; } public static void main(String[] args) { Coin coin = quarter; System.err.println(quarter.getValue()); } }
这里还有一个张孝祥师傅讲解的交通灯控制中使用的枚举的综合运用。
public enum Lamp { /*每个枚举元素各表示一个方向的控制灯*/ S2N("N2S","S2W",false),S2W("N2E","E2W",false),E2W("W2E","E2S",false),E2S("W2N","S2N",false), /*下面元素表示与上面的元素的相反方向的灯,它们的“相反方向灯”和“下一个灯”应忽略不计!*/ N2S(null,null,false),N2E(null,null,false),W2E(null,null,false),W2N(null,null,false), /*由南向东和由西向北等右拐弯的灯不受红绿灯的控制,所以,可以假想它们总是绿灯*/ S2E(null,null,true),E2N(null,null,true),N2W(null,null,true),W2S(null,null,true); private Lamp(String opposite,String next,boolean lighted){ this.opposite = opposite; this.next = next; this.lighted = lighted; } /*当前灯是否为绿*/ private boolean lighted; /*与当前灯同时为绿的对应方向*/ private String opposite; /*当前灯变红时下一个变绿的灯*/ private String next; public boolean isLighted(){ return lighted; } /** * 某个灯变绿时,它对应方向的灯也要变绿 */ public void light(){ this.lighted = true; if(opposite != null){ Lamp.valueOf(opposite).light(); } System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!"); } /** * 某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿 * @return 下一个要变绿的灯 */ public Lamp blackOut(){ this.lighted = false; if(opposite != null){ Lamp.valueOf(opposite).blackOut(); } Lamp nextLamp= null; if(next != null){ nextLamp = Lamp.valueOf(next); System.out.println("绿灯从" + name() + "-------->切换为" + next); nextLamp.light(); } return nextLamp; } }