6

java enum枚举类型用法小结

 3 years ago
source link: https://blogread.cn/it/article/8075?f=hot1
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

java enum枚举类型用法小结

浏览:1079次  出处信息

本文总结了一些有关java中enum枚举类型的用法,下面是一个示例:

public enum EnumTest {
  FRANK("The given name of me"), LIU("The family name of me");
  private String context;

  private String getContext() {
    return this.context;
  }

  private EnumTest(String context) {
    this.context = context;
  }

  public static void main(String[] args) {
    for (EnumTest name : EnumTest.values()) {
      System.out.println(name + " : " + name.getContext());
    }
    System.out.println(EnumTest.FRANK.getDeclaringClass());
  }
}

java中枚举实现的分析:

public enum Color {
  RED, BLUE, BLACK, YELLOW, GREEN
}

显然,enum很像特殊的class,实际上enum声明定义的类型就是一个类。而这些类都是类库中Enum类的子类(java.lang.Enum<E>),它们继承了这个Enum中的许多有用的方法。

下面我们就详细介绍enum定义的枚举类的特征及其用法(后面均用Color举例):

1、Color枚举类就是class,而且是一个不可以被继承的final类。其枚举值(RED,BLUE...)都是Color类型的类静态常量, 我们可以通过下面的方式来得到Color枚举类的一个实例:Color c=Color.RED;

注意:这些枚举值都是public static final的,也就是我们经常所定义的常量方式,因此枚举类中的枚举值最好全部大写。

2、即然枚举类是class,当然在枚举类型中有构造器,方法和数据域。但是,枚举类的构造器有很大的不同:

(1)构造器只是在构造枚举值的时候被调用。

enum Color {
  RED(255, 0, 0), BLUE(0, 0, 255), BLACK(0, 0, 0), YELLOW(255, 255, 0), GREEN(
      0, 255, 0);
  // 构造枚举值,比如RED(255,0,0)
  private Color(int rv, int gv, int bv) {
    this.redValue = rv;
    this.greenValue = gv;
    this.blueValue = bv;
  }

  public String toString() { // 覆盖了父类Enum的toString()
    return super.toString() + "(" + redValue + "," + greenValue + ","
        + blueValue + ")";
  }

  private int redValue; // 自定义数据域,private为了封装。
  private int greenValue;
  private int blueValue;
}

(2)构造器只能私有private,绝对不允许有public构造器。这样可以保证外部代码无法新构造枚举类的实例。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。但枚举类的方法和数据域可以允许外部访问。

public class TestMain {
  public static void main(String args[]) {
    // Color colors=new Color(100,200,300); //wrong
    Color color = Color.RED;
    System.out.println(color); // 调用了toString()方法
  }
}

3、所有枚举类都继承了Enum的方法,下面我们详细介绍这些方法。

(1)ordinal()方法: 返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定。

Color.RED.ordinal();  //返回结果:0
Color.BLUE.ordinal();  //返回结果:1

(2)compareTo()方法: Enum实现了java.lang Comparable接口,因此可以比较象与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。(具体可见源代码)

Color.RED.compareTo(Color.BLUE);  //返回结果 -1

(3)values()方法:静态方法,返回一个包含全部枚举值的数组。

Color[] colors=Color.values();
for(Color c:colors){
	System.out.print(c+","); 
} //返回结果:RED,BLUE,BLACK YELLOW,GREEN,

(4)toString()方法:返回枚举常量的名称。

Color c=Color.RED;
System.out.println(c);//返回结果: RED

(5)valueOf()方法:这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量。

Color.valueOf("BLUE");   //返回结果: Color.BLUE

(6)equals()方法:比较两个枚举类对象的引用。

//JDK源代码:      
public final boolean equals(Object other) {  
  return this==other;  
}

4、枚举类可以在switch语句中使用。

Color color=Color.RED;  
switch(color){  
  case RED: System.out.println("it's red");break;  
  case BLUE: System.out.println("it's blue");break;  
  case BLACK: System.out.println("it's blue");break;  
}

enum类型有如下几种常见用法:

用法一:常量

在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

public enum Color {
  RED, GREEN, BLANK, YELLOW
}

用法二:switch

JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。

enum Signal {
  GREEN, YELLOW, RED
}

public class TrafficLight {
  Signal color = Signal.RED;

  public void change() {
    switch (color) {
    case RED:
      color = Signal.GREEN;
      break;
    case YELLOW:
      color = Signal.RED;
      break;
    case GREEN:
      color = Signal.YELLOW;
      break;
    }
  }
}

用法三:向枚举中添加新方法

如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。

public enum Color {
  RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
  // 成员变量
  private String name;
  private int index;

  // 构造方法
  private Color(String name, int index) {
    this.name = name;
    this.index = index;
  }

  // 普通方法
  public static String getName(int index) {
    for (Color c : Color.values()) {
      if (c.getIndex() == index) {
        return c.name;
      }
    }
    return null;
  }

  // get set 方法
  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getIndex() {
    return index;
  }

  public void setIndex(int index) {
    this.index = index;
  }
}

用法四:覆盖枚举的方法

下面给出一个toString()方法覆盖的例子。

public class Test {
  public enum Color {
    RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
    // 成员变量
    private String name;
    private int index;

    // 构造方法
    private Color(String name, int index) {
      this.name = name;
      this.index = index;
    }

    // 覆盖方法
    @Override
    public String toString() {
      return this.index + "_" + this.name;
    }
  }

  public static void main(String[] args) {
    System.out.println(Color.RED.toString());
  }
}

用法五:实现接口

所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。

public interface Behaviour {
  void print();

  String getInfo();
}

public enum Color implements Behaviour {
  RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
  // 成员变量
  private String name;
  private int index;

  // 构造方法
  private Color(String name, int index) {
    this.name = name;
    this.index = index;
  }

  // 接口方法

  @Override
  public String getInfo() {
    return this.name;
  }

  // 接口方法
  @Override
  public void print() {
    System.out.println(this.index + ":" + this.name);
  }
}

用法六:使用接口组织枚举

public interface Food {
  enum Coffee implements Food {
    BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO
  }

  enum Dessert implements Food {
    FRUIT, CAKE, GELATO
  }
}
}

用法七:关于枚举集合的使用

java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。

/**
 * 枚举类型的完整演示代码
 */
import java.util.EnumMap;
import java.util.EnumSet;

public class LightTest {
  // 1.定义枚举类型
  public enum Light {
    // 利用构造函数传参
    RED(1), GREEN(3), YELLOW(2);
    // 定义私有变量
    private int nCode;

    // 构造函数,枚举类型只能为私有
    private Light(int _nCode) {
      this.nCode = _nCode;
    }

    @Override
    public String toString() {
      return String.valueOf(this.nCode);
    }
  }

  /**
   * 
   * @param args
   */

  public static void main(String[] args) {
    // 1.遍历枚举类型
    System.out.println("演示枚举类型的遍历 ......");
    testTraversalEnum();
    // 2.演示EnumMap对象的使用
    System.out.println("演示EnmuMap对象的使用和遍历.....");
    testEnumMap();
    // 3.演示EnmuSet的使用
    System.out.println("演示EnmuSet对象的使用和遍历.....");
    testEnumSet();
  }

  /**
   * 
   * 演示枚举类型的遍历
   */

  private static void testTraversalEnum() {
    Light[] allLight = Light.values();
    for (Light aLight : allLight) {
      System.out.println("当前灯name:" + aLight.name());
      System.out.println("当前灯ordinal:" + aLight.ordinal());
      System.out.println("当前灯:" + aLight);
    }
  }

  /**
   * 
   * 演示EnumMap的使用,EnumMap跟HashMap的使用差不多,只不过key要是枚举类型
   */

  private static void testEnumMap() {
    // 1.演示定义EnumMap对象,EnumMap对象的构造函数需要参数传入,默认是key的类的类型
    EnumMap<Light, String> currEnumMap = new EnumMap<Light, String>(
        Light.class);
    currEnumMap.put(Light.RED, "红灯");
    currEnumMap.put(Light.GREEN, "绿灯");
    currEnumMap.put(Light.YELLOW, "黄灯");
    // 2.遍历对象
    for (Light aLight : Light.values()) {
      System.out.println("[key=" + aLight.name() + ",value="
          + currEnumMap.get(aLight) + "]");
    }

  }

  /**
   * 
   * 演示EnumSet如何使用,EnumSet是一个抽象类,获取一个类型的枚举类型内容可以使用allOf方法
   */

  private static void testEnumSet() {
    EnumSet<Light> currEnumSet = EnumSet.allOf(Light.class);
    for (Light aLightSetElement : currEnumSet) {
      System.out.println("当前EnumSet中数据为:" + aLightSetElement);
    }
  }

}

参考资料:

建议继续学习:

QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK