JDK 1.5 新特性之枚举值与枚举类

JDK 1.5 新特性之枚举值与枚举类

      • JDK 15 新特性之枚举值与枚举类
        • 需求
        • 设计弊端
        • 初次改进
        • 二次改进
        • 枚举类及其改进
        • 枚举类需要注意的地方

需求

在其它的编程语言中,也有类似枚举的概念,并且也定义了枚举的使用方法,但是我觉得Java中的枚举更加的灵活更加的强大,这可能也是Java一直很受欢迎的原因之一:灵活、统一。在平时的编程过程中我们经常会遇到下面的需求:表示一个星期、表示性别、表示一年四季等等,很明显,这些需求的共同特征是:都有一个固定的取值范围,并且取值不能随意,很显然,目前我们可以通过仔细的设计去实现这个需求,但是Java同样考虑到了这个问题,下面我会通过详细的代码设计去解决这个问题。

设计弊端

首先看下面的一段代码:

package io.uniplore;

public class Person {
    @Override
    public String toString() {
        return "Person [name=" + name + ", gender=" + gender + ", ID=" + ID + "]";
    }
    private String name;
    private String gender;
    private String ID;
    public Person(String name, String gender, String ID) {
        this.name = name;
        this.gender = gender;
        this.ID = ID;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public String getID() {
        return ID;
    }
    public void setID(String iD) {
        ID = iD;
    } 
}

//主函数
public class TestEnum {
    public static void main(String[] args) {
        Person p = new Person("小明","男","1234567890");
        p.setGender("人妖");
        System.out.println(p);
    }
}

从上面的代码中可以看出,在给性别赋值时,不能控制性别为男或者女,存在很大的问题,该段代码的弊端是:变量的随意赋值没有限制。

初次改进

本次改进中,在需要用户设置性别属性的时候,进行了条件判断,要求如果输入非男也非女时,循环让用户重新输入,直到输入正确的结果为止,这种方法显然增加了编程人员写代码的复杂度,并且很繁琐感觉。

package io.uniplore;

import java.util.Scanner;

public class Person {

    @Override
    public String toString() {
        return "Person [name=" + name + ", gender=" + gender + ", ID=" + ID + "]";
    }
    private String name;
    private String gender;
    private String ID;
    public Person(String name, String gender, String ID) {
        this.gender = gender;
        this.name = name;
        this.ID = ID;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        boolean flag = true;
        Scanner scanner = new Scanner(System.in);
        while(flag){
            if ("男".equals(gender) || "女".equals(gender)) {
                this.gender = gender;
                flag = false;
            }else{
                System.out.print("您输入的性别只能是男或者女,请重新输入:");
                gender = scanner.nextLine();
            }
        }
    }
    public String getID() {
        return ID;
    }
    public void setID(String iD) {
        ID = iD;
    } 
}

//主函数
public class TestEnum {
    public static void main(String[] args) {
        Person p = new Person("小明","人妖","1234567890");
        System.out.println(p);
        p.setGender("人妖");
        System.out.println(p);
    }

}

二次改进

这样的控制过程显得十分的繁琐,我有一个新的想法,创建一个单独的Gender类,然后其中有两个常量供我们使用,看下面的代码:

package io.uniplore.enum1;

class Gender {
    String value;
    @Override
    public String toString() {
        return "Gender [value=" + value + "]";
    }

    public static final Gender man = new Gender("男");  //调用私有构造函数进行初始化
    public static final Gender women = new Gender("女");

    private Gender(String value) {  //构造函数初始化能够防止用户随意创建对象
        this.value = value;
    } 
}

class Person1{
    @Override
    public String toString() {
        return "Person1 [sex=" + sex + ", name=" + name + ", ID=" + ID + "]";
    }
    Gender sex;
    String name;
    String ID;
    public Gender getSex() {
        return sex;
    }
    public void setSex(Gender sex) {
        this.sex = sex;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getID() {
        return ID;
    }
    public void setID(String iD) {
        ID = iD;
    }
}

public class run {

    public static void main(String[] args) {
        Person1 p = new Person1();
        p.setSex(Gender.man);
        p.setSex(Gender.women);
        System.out.println(p.toString());
    }
}

本次改进明显的比上一次更加的好,并且严格的限制了性别的取值只能是男或者女,但是这种改变实际上还是需要编程人员写很多的代码,在JDK 1.5 之后增加了枚举类,使得整个过程更加的简洁,下面首先介绍枚举类,然后再此基础之上进行最后一次改进。

枚举类及其改进

枚举类是在JDK 1.5引入的新特性,枚举类实际上通过JVM加载之后,就会变成一个类,并且其中的枚举常量也变成了public static final类型,也就是整个过程是及其相似的,并且在枚举类中依旧可以定义成员方法和成员变量,同时也能定义抽象方法,但是由于静态的对象也能调用抽象方法,所以必须在静态变量中实现抽象方法,这是符合事实的,但是这种用法显然不多,我们最多用的是枚举类中的枚举值。

enum Sex{
    man("男"){
        @Override
        public void run() {
            System.out.println("男人在跑...");
        }
    },woman("女"){
        @Override
        public void run() {
            System.out.println("女人在跑...");
        }
    }; //枚举值

    String value; //成员变量
    // public static final Sex man = new Sex();


    //构造函数
    private Sex(String  value){
        this.value = value;
    }

    //成员函数
    public void getValue(){
        System.out.println("value :"+ value);
    }

    public abstract void run();

}

public class Demo{

    public static void main(String[] args) {
        Sex sex = Sex.man; //获取到了枚举类的对象
        sex.value = "男";
        sex.getValue();
        sex.run();

    }

}

枚举类需要注意的地方

  1. 枚举类也是一个特殊的类。
  2. 枚举值默认的修饰符是public static final。
  3. 枚举值就是是枚举值所属的类的类型, 然后枚举值是指向了本类的对象的。
  4. 枚举类的构造方法默认的修饰符是private的。
  5. 枚举类可以定义自己的成员变量与成员函数。
  6. 枚举类可以自定义构造函数,但是构造函数的修饰符必须是private。
  7. 枚举类可以存在抽象的方法,但是枚举值必须要实现抽象的方法。
  8. 枚举值必须要位于枚举类的第一个语句。

你可能感兴趣的:(java,编程语言,Class,需求,java枚举)