您的位置 首页 java

JAVA基本功之枚举,掌握本质从此不再朦朦胧胧

概述:

最简单的枚举形式就是用来定义新数据类型的命名常量列表, 枚举类型 的对象只能包含该列表定义的值。因此,枚举为精准定义包含固定条目有效值的新数据类型提供了一种方式。

枚举在日常生活中很常见。例如,月份的枚举包含1月到12月这12个数据,一周各天的枚举是星期一、星期二、星期三、星期四、星期五、星期六和星期天。

从编程的角度来看,枚举在需要定义一组代表条目集合的值时很有用。例如,可使用枚举来代表一组状态代码,例如:成功、失败、等待和重试等来表示某种动作的进度。在过去,我们把这种值定义为final的,但是用枚举就显得更加结构化,我们通过示例代码( 列出各种交通工具 )来体会一下这两种实现方式的差别:

用final修饰的方式:

/**
 * Created by 摆技
 */public class Transport {
 public static final int CAR =1;
 public static final int TRUCK=2;
 public static final int AIRPLANE=3;
 public static final int TRAIN=4;
 public static final int BOAT=5;
}
 

枚举方式:

/**
 * Created by 摆技
 */public  enum  TransportEnum {
 CAR, TRUCK, AIRPLANE, TRAIN, BOAT
}
 

枚举的基础知识

枚举用enum关键字创建,在上例中,标识符CAR、TRUCK等称为枚举常量,它们都被隐式的声明为一个public final static的TransportEnum的成员。在java中,这些常量被称为自我类型化(self-typed)。

定义了枚举之后,我们可以创建枚举的常量。但是尽管枚举定义了一个类类型,却不能使用new来 实例化 。应该像处理基本数据类型那样来声明和使用枚举变量。例如:

TransportEnum tp;
 

由于tp是TransportEnum类型的,因此只能向他赋值枚举定义的值:

tp = TransportEnum.TRAIN;
 

可以使用关系运算符==来判断两个枚举常量是否相等。例如:

if(tp == TransportEnum.TRAIN) // ...
 

还可以使用枚举值来控制 switch 语句,当然,所有的case语句都必须使用来自switch表达式所用枚举中的 Enum 常量。例如:

/**
 * Created by 摆技
 */public class Test {
 public static void main(String[] args) {
 TransportEnum tp = TransportEnum.TRAIN;
 switch(tp) {
 case CAR:
 // TODO
  break ;
 case TRUCK:
 // TODO
 break;
 case AIRPLANE:
 // TODO
 break;
 case TRAIN:
 // TODO
 break;
 case BOAT:
 // TODO
 break;
 default:
 // TODO
 }
 }
}
 

注意,在case语句中,枚举常量的名称没有使用枚举类型名称来限制,也就是说,使用TRAIN而不是TransportEnum.TRAIN。这是因为switch表达式中的枚举类型已经隐式的制定了case常量的枚举类型,也就没有必要使用枚举类型名称来限定了。

JAVA中的枚举本质上是类类型

前面的实例中,虽然说明了如何创建和使用枚举,但是并没有揭示的全部功能。与其他语言实现枚举的方式不同,JAVA将枚举实现没类类型。尽管不会使用new实例化枚举,但是枚举的表现非常像其他类类型, 本质上使用enum关键字创建的枚举类型并编译后事实上也是一个类类型而且该类是fianl的并且还继承了java.lang.Enum 。这使得JAVA的枚举有了其他更为强大的功能,例如,可以给枚举提供 构造方法 ,添加实例变量和实例方法。甚至实现接口。

下面我们需要了解一下values()和valueOf()方法,所有枚举都拥有这两个预定的方法。它们的基本形式如下图所示:

public static enum-type[] values();
public static enum-type valueOf(String str);
 

Values()方法返回一个包含枚举常量列表的数组。valueOf()方法返回一个枚举常量,其值对应传进来的str字符串。这两个方法中enum-type是相同的。例如前面的TransportEnum枚举中,TransportEnum.valueOf(“TRAIN”)的返回值类型是TransportEnum,返回值是TRAIN。下面的程序演示了values()和valueOf()方法:

/**
 * Created by 摆技
 */public class Test {
 public static void main(String[] args) {
 System.out.println("列出所有交通工具:");
 //使用values()方法
 TransportEnum[]  tps  = TransportEnum.values();
 for(TransportEnum tp : tps) {
 System.out.println(tp);
 }
 System.out.println("-----------------------------");
 //使用valueOf()
 TransportEnum tp = TransportEnum.valueOf("TRAIN");
 System.out.println(tp);
 }
}
 

枚举类型的构造方法、成员方法、成员变量

每一个枚举常量都是一个枚举类型的对象,理解这一点很重要。因此,枚举可以定义构造方法、成员方法和成员变量。以下三点需要掌握:

1)当定义枚举的构造方法的时候,会在创建每个枚举常量的时候调用。

2)每个枚举常量都可以调用枚举定义的任何成员方法。

3)每个枚举常量都包含实例变量的副本。

我们通过改造TransportEnum(为每种交通工具提供一种常见的速度)来验证以上三点:

/**
 * Created by 摆技
 */public enum TransportEnum {
 CAR(65), TRUCK(55), AIRPLANE(600), TRAIN(70), BOAT(22);
 // 为交通工具提供 speed 属性
 private int speed;
 TransportEnum(int speed) {
 this.speed = speed;
 }
 int getSpeed() {
 return this.speed;
 }
}
 

我们给TransportEnum添加了四项内容:

1)实例变量speed,用来保存每种交通工具的速度。

2)TransportEnum(int)构造方法

3)getSpeed()方法,返回speed的值

4)通过在常量后面添加()的方式指定构造方法的实参

总结:

你可记得,前面我们说过枚举本质上是类类型。每一个枚举被编译之后,都会变成一个final的类( 所以枚举有一个限制是不能被继承 ),并且该类继承了java.lang.Enum( 所以枚举还有一个限制是不能继承另一个类 ),这是枚举的本质。请务必牢记!!!

既然枚举是继承了java.lang.Enum的类,那么大家看完文章后有没有必要回去找找API,看看java.lang.Enum类都有什么方法?

此处,我给大家一个问题,大家可以在评论区讨论:

我们说枚举可以替换final变量的方式,那么JAVA枚举的出现,使得final变量过时了吗?

文章来源:智云一二三科技

文章标题:JAVA基本功之枚举,掌握本质从此不再朦朦胧胧

文章地址:https://www.zhihuclub.com/185372.shtml

关于作者: 智云科技

热门文章

网站地图