您的位置:首页 > 编程语言 > Java开发

Java编程思想学习(十四) 枚举

2016-03-13 20:56 323 查看
关键字enum可以将一组具名的值有限集合创建一种为新的类型,而这些具名的值可以作为常规的程序组件使用。

基本enum特性

调用enum的values()方法可以遍历enum实例,values()方法返回enum实例数组,且数组中元素保持在enum声明时的顺序。

publicclassTestEnum{
publicstaticvoidmain(String[]args){
Fruit[]values=Fruit.values();
for(Fruitfruit:values){
System.out.println(fruit);
printEnum(fruit);
}
}

publicenumFruit{
APPLE,ORANGE,WATERMELON
}

publicstaticvoidprintEnum(Fruitfruit){
//顺序
System.out.println(fruit+"ordinal:"+fruit.ordinal());
//比较(ordinal值)
System.out.println("comparetoapple"+fruit.compareTo(Fruit.APPLE));
//==
System.out.println(fruit==Fruit.ORANGE);
//获取所属的enum类
System.out.println(fruit.getDeclaringClass());
//获取名字
System.out.println(fruit.name());
}
}

//output
/**
APPLE
ORANGE
WATERMELON
*/

/**
APPLEordinal:0
comparetoapple0
false
classcom.TestEnum$Fruit
APPLE
ORANGEordinal:1
comparetoapple1
true
classcom.TestEnum$Fruit
ORANGE
WATERMELONordinal:2
comparetoapple2
false
classcom.TestEnum$Fruit
WATERMELON
*/



ordinal()方法返回int值:表示enum实例在声明时的次序,从0开始。
使用==来比较enum实例。


将静态导入用于enum

使用staticimport能够将enum实例的标识符带入当前命名空间,无需再用emum类型来修饰enum实例。
importstatic---->MALE
import---->Gender.MALE

packagecom;

importstaticcom.Gender.*;

/**
*CreatedbyJohnTsaion15/10/22.
*/
publicclassTestStaticImport{
Gendergender;

publicstaticvoidmain(String[]args){
System.out.println(newTestStaticImport(MALE));
System.out.println(newTestStaticImport(FEMALE));
}

publicTestStaticImport(Gendergender){
this.gender=gender;
}

@Override
publicStringtoString(){
return"GENDERis"+this.gender;
}
}


enum中的构造器与方法和普通的类没有区别,除了少数限制外,enum就是一个普通的类。(一般只使用普通的枚举类型)
需先定义enum实例,然后再定义自己的方法。

packagecom;

/**
*CreatedbyJohnTsaion15/10/23.
*/
publicenumDirection{
//最先定义enum实例
WEST("thisiswest"),EAST("thisiseast"),NORTH("thisisnorth"),SOUTH("thisissouth");
//要定义自己的方法,需在定义的enum实例后加分号

privateStringtext;
privateDirection(Stringtext){
this.text=text;
}
publicStringgetText(){
returnthis.text;
}

publicstaticvoidmain(String[]args){
for(Directiondirection:Direction.values()){
System.out.println(direction+":"+direction.getText());
}
}

}


覆盖enum的方法

覆盖enum的toString()方法和覆盖一般类的方法没有区别。

switch语句中的enum

enum提供了非常便利的功能:在switch中使用enum。

packagecom;

/**
*CreatedbyJohnTsaion15/10/23.
*/
enumSignal{
GREEN,YELLOW,RED
}

publicclassTrafficLight{
Signalcolor=Signal.GREEN;

publicvoidchange(){
switch(color){
caseRED:
color=Signal.GREEN;
break;
caseGREEN:
color=Signal.YELLOW;
break;
caseYELLOW:
color=Signal.RED;
break;
}
}

@Override
publicStringtoString(){
return"trafficlightis"+color;
}

publicstaticvoidmain(String[]args){
TrafficLightlight=newTrafficLight();
for(inti=0;i<10;i++){
System.out.println(light);
light.change();
}
}
}


values()的神秘之处

编译器为我们创建的enum类都继承自Enum类。
但是Enum类中并没有values()方法。

packagecom;

importjava.lang.reflect.Method;
importjava.lang.reflect.Type;
importjava.util.Set;
importjava.util.TreeSet;

/**
*CreatedbyJohnTsaion15/10/25.
*/
enumExplore{
HERE,THERE
}
publicclassReflection{
publicstaticSet<String>analyse(Class<?>enumClass){
println("Analyzingbegin:");
println("Interfaces:");
for(Typet:enumClass.getGenericInterfaces()){
print(t.toString());
}
println("Base:"+enumClass.getSuperclass());
println("Methods:");
Set<String>methods=newTreeSet<>();
for(Methodm:enumClass.getMethods()){
methods.add(m.getName());
}
println(methods.toString());
returnmethods;
}

publicstaticvoidprintln(Strings){
System.out.println(s);
}

publicstaticvoidprint(Strings){
System.out.print(s);
}

publicstaticvoidmain(String[]args){
Set<String>exploreMethods=analyse(Explore.class);
Set<String>enumMethods=analyse(Enum.class);
println("ExplorecontainsAll(Enum)?"+exploreMethods.containsAll(enumMethods));
println("ExploreremoveAll(Enum)"+exploreMethods.removeAll(enumMethods));

println(exploreMethods.toString());
}
}

//output:
/**Analyzingbegin:
Interfaces:
Base:classjava.lang.Enum
Methods:
[compareTo,equals,getClass,getDeclaringClass,hashCode,name,notify,notifyAll,ordinal,toString,valueOf,values,wait]
Analyzingbegin:
Interfaces:
java.lang.Comparable<E>interfacejava.io.SerializableBase:classjava.lang.Object
Methods:
[compareTo,equals,getClass,getDeclaringClass,hashCode,name,notify,notifyAll,ordinal,toString,valueOf,wait]
ExplorecontainsAll(Enum)?true
ExploreremoveAll(Enum)true
[values]
*/


反编译之前的枚举类型Gender

javacGender.class
javapGender

Compiledfrom"Gender.java"
publicfinalclasscom.Genderextendsjava.lang.Enum<com.Gender>{
publicstaticfinalcom.GenderMALE;
publicstaticfinalcom.GenderFEMALE;
publicstaticcom.Gender[]values();
publicstaticcom.GendervalueOf(java.lang.String);
static{};
}

values()是由编译器添加的static方法。编译器还添加了valueOf()方法。
添加的这个valueOf()方法和Enum中的valueOf()方法不同。前者只有一个参数而后者有两个。

由于values()方法是由编译器插入到enum定义的static方法,当enum实例向上转型为Enum,values()方法就不能调用了。
Class中有个getEnumConstants()方法可以获取到所有enum实例。

packagecom;

/**
*CreatedbyJohnTsaion15/10/25.
*/
publicclassUpcastEnum{
publicstaticvoidmain(String[]args){
Gender[]values=Gender.values();
Enume=Gender.MALE;
//e.values();Novalues()inEnum
for(Enumen:e.getClass().getEnumConstants()){
System.out.println(en);
}
}
}

//output
/**
MALE
FEMALE
*/


实现,而非继承

所有的enum都继承自java.lang.Enum类。

System.out.println("Gender'ssuperclass:"+Gender.class.getSuperclass());
//output:
//Gender'ssuperclass:classjava.lang.Enum


由于java不支持多继承,所以enum不能再继承其他类了。然而,我们可以在创建一个新的enum时,可以同时实现一个或多个接口。

转载:/content/4151472.html


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
章节导航