java 枚举的学习和使用

最近在看别人的代码的时候,经常会看到有使用到枚举的地方,但是在自己写的时候,也有想到过用枚举,但是对什么时候使用枚举和 常量 没有一个明确的概念,比较模糊。所以特别整理了一下有关枚举的知识,以供学习使用。

1.什么java 的枚举类型

以我的理解答:枚举是我们自己定义的一个集合,比如说我们数学里面所学的集合A={1、2、3},当我们要使用A这个集合的时候,我们只能够使用集合A里面的1、2、3这三个元素,不是A里面的元素我们就不可以使用。
同样,枚举和这个集合是类似的,当我们定义了一个枚举类型的时候,我们声明它里面有几个元素,在我们使用这个枚举的时候,我们只能够使用它有的元素,没有的元素我们是无法使用,系统就会报错!
枚举还有一个特点,就是可以代表数值,比如说第一个定义的元素对应的值为0,每个枚举元素从0开始,逐一增加。此时,这个数值也代表他们本身,相当于每一个元素有两个名字。

2.什么情况下使用枚举类型

2.1 什么情况下使用枚举类?
  有的时候一个类的对象是有限且固定的,这种情况下我们使用枚举类就比较方便.
  
2.2 为什么不用静态常量来替代枚举类呢?

   public static final int SEASON_SPRING = 1;
  public static final int SEASON_SUMMER = 2;
  public static final int SEASON_FALL = 3;
  public static final int SEASON_WINTER = 4;

 枚举类更加直观,类型安全。使用常量会有以下几个缺陷:
  1. 类型不安全。若一个方法中要求传入季节这个参数,用常量的话,形参就是int类型,开发者传入任意类型的int类型值就行,但是如果是枚举类型的话,就只能传入枚举类中包含的对象。
  2. 没有命名空间。开发者要在命名的时候以SEASON_开头,这样另外一个开发者再看这段代码的时候,才知道这四个常量分别代表季节。

2.3 常使用的地方:
我们要从另一个函数得到一个值,但是这个值只能够在一个范围内的,此时我们就可以使用枚举来定义这个范围。限制另外一个函数能够传递进来的值,只能够是枚举类型里面的元素

3.枚举类的简单使用和注意点

package enumcase;
  public enum SeasonEnum {
  SPRING,SUMMER,FALL,WINTER;
  }

然后可以这样来使用:SeasonEnum currentSeason = SeasonEnum .SUMMER

注意:
(1) enum和class、interface的地位一样
(2) 使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类。枚举类可以实现一个或多个接口。
(3) 枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。
(4) 使用enum定义、非抽象的枚举类默认使用final修饰,不可以被继承。
(5) 枚举类的构造器只能是私有的。

3.1枚举类内也可以定义属性和方法,可是是静态的和非静态的。

package enumcase;
  public enum SeasonEnum {
      SPRING("春天"),
      SUMMER("夏天"),
      FALL("秋天"),
      WINTER("冬天");
  
  private final String name;
  
  private SeasonEnum(String name)
  {
     this.name = name;
  }
  public String getName() {
    return name;
  }
 }

实际上在第一行写枚举类实例的时候,默认是调用了构造器的,所以此处需要传入参数,因为没有显式申明无参构造器,只能调用有参数的构造器。
  构造器需定义成私有的,这样就不能在别处申明此类的对象了。枚举类通常应该设计成不可变类,它的Field不应该被改变,这样会更安全,而且代码更加简洁。所以我们将Field用private final修饰。

3.2 枚举类遍历
枚举类型提供了两个有用的静态方法 values( ) 和 valueOf( ) 我们可以很方便的使用它们
例如:

 for(SeasonEnum s : SeasonEnum .values())
     System.out.println(s);

3.3 switch语句里的表达式可以是枚举值

package enumcase;
public class SeasonTest {
    
    
 public void judge(SeasonEnum s){
  switch(s){
      case SPRING:
        System.out.println("春天适合踏青。");
      break;
      case SUMMER:
        System.out.println("夏天要去游泳啦。");
      break;
      case FALL:
        System.out.println("秋天一定要去旅游哦。");
      break;
      case WINTER:
        System.out.println("冬天要是下雪就好啦。");
      break;
  }
 }
 
public static void main(String[] args) {
  SeasonEnum s = SeasonEnum.SPRING;
  SeasonTest test = new SeasonTest();
  test.judge(s);
  }
}

3.4 定义枚举类型时本质上就是定义一个类别,只不过很多细节由编译器帮我们完成了,所以某些程度上,enum关键字的作用 就像是class或interface

3.5 使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类

当我们使用“enum”定义枚举类型时,实质上我们定义出来的类型继承自java.lang.Enum类型,而枚举的成员其实就是我们定义的枚举类型的一个实例(Instance),他们都被预设为final,所以我们无法改变他们,他们也是static成员,所以我们可以通过类型名称直接使用他们,当然最重要的,他们都是公开的(public)。即,我们定义的每个枚举类型都继承自java.lang.Enum类,枚举中的每一个成员默认都是public static final 的。
而每个枚举的成员其实就是我们定义的枚举类型的一个实例(Instance)。换句话说,当定义了一个枚举类型后,在编译时刻就能确定该枚举类型有几个实例,分别是什么。在运行期间我们无法再使用该枚举类型创建新的实例了,这些实例在编译期间就已经完全确定下来了。 所以在:SeasonEnum currentSeason = SeasonEnum .SUMMER 中,没有new SeasonEnum ()。而是直接赋值

3.6 检查权限

如一个经理、员工、顾客对一个工具的使用权限,一般用枚举来处理 因为这样子可以用来控制传入判断的参数只能够是该枚举类型的数,从而限制传入的参数.

package Enum;

public class AccessControl {
    
    
    public static boolean checkRight(AccessRight access){
        if(access == AccessRight.MANAGER){
            return true;
        }
        else if(access == AccessRight.DEPARMENT){
           return false;
        }else {
          return false;
        }

    public static void main(String[] args) {
        System.out.println(checkRight(AccessRight.DEPARMENT));
    }
}

enum AccessRight{
MANAGER,DEPARMENT,EMPLOYEE;

通过这样,只能够传递AccessRight类型的参数,其他参数都是不合法的。

3.7 将String类型转换为枚举类型

static <T extends Enum<T>> T 
valueOf(Class<T> enumType, String name) 

返回带指定名称的指定枚举类型的枚举常量。

可以这样子使用 AccessRight access = AccessRight.valueOf(“MANAGER”);//只要AccessRight中有MANAGER的元素就可以返回这个元素,即将String类型转换为AccessRight类型

4.参考的网站

至此枚举学习了很多,对于网上的一些东西稍微整理,下面我是我借鉴的一些网站

https://www.douban.com/note/512891241/
http://blog.sina.com.cn/s/blog_4adc4b090101dtxp.html
http://blog.sina.com.cn/s/blog_697b968901013ih1.html

猜你喜欢

转载自blog.csdn.net/android_freshman/article/details/52223542