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


     关键字enum可以将一组具名的值有限集合创建一种为新的类型,而这些具名的值可以作为常规的程序组件使用。

    基本enum特性

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

     1 public class TestEnum {
     2     public static void main(String[] args) {
     3         Fruit[] values = Fruit.values();
     4         for (Fruit fruit : values) {
     5             System.out.println(fruit);
     6             printEnum(fruit);
     7         }
     8     }
     9 
    10     public enum Fruit {
    11         APPLE, ORANGE, WATERMELON
    12     }
    13 
    14    public static void printEnum(Fruit fruit) {
    15         //顺序
    16         System.out.println(fruit + " ordinal:" + fruit.ordinal());
    17         //比较(ordinal值)
    18         System.out.println("compare to apple" + fruit.compareTo(Fruit.APPLE));
    19         //==
    20         System.out.println(fruit == Fruit.ORANGE);
    21         //获取所属的enum类
    22         System.out.println(fruit.getDeclaringClass());
    23         //获取名字
    24         System.out.println(fruit.name());
    25     }
    26 }
    27 
    28 //output
    29 /**
    30 APPLE
    31 ORANGE
    32 WATERMELON
    33 */
    34 
    35 /**
    36 APPLE ordinal:0
    37 compare to apple0
    38 false
    39 class com.TestEnum$Fruit
    40 APPLE
    41 ORANGE ordinal:1
    42 compare to apple1
    43 true
    44 class com.TestEnum$Fruit
    45 ORANGE
    46 WATERMELON ordinal:2
    47 compare to apple2
    48 false
    49 class com.TestEnum$Fruit
    50 WATERMELON
    51 */

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

    将静态导入用于enum

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

     1 package com;
     2 
     3 import static com.Gender.*;
     4 
     5 /**
     6  * Created by JohnTsai on 15/10/22.
     7  */
     8 public class TestStaticImport {
     9     Gender gender;
    10 
    11     public static void main(String[] args) {
    12         System.out.println(new TestStaticImport(MALE));
    13         System.out.println(new TestStaticImport(FEMALE));
    14     }
    15 
    16     public TestStaticImport(Gender gender) {
    17         this.gender = gender;
    18     }
    19 
    20     @Override
    21     public String toString() {
    22         return "GENDER is" + this.gender;
    23     }
    24 }

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

     1 package com;
     2 
     3 /**
     4  * Created by JohnTsai on 15/10/23.
     5  */
     6 public enum Direction {
     7     //最先定义enum实例
     8     WEST("this is west"),EAST("this is east"),NORTH("this is north"),SOUTH("this is south");
     9     //要定义自己的方法,需在定义的enum实例后加分号
    10 
    11     private String text;
    12     private Direction(String text){
    13         this.text = text;
    14     }
    15     public String getText(){
    16         return this.text;
    17     }
    18 
    19     public static void main(String[] args) {
    20         for(Direction direction:Direction.values()){
    21             System.out.println(direction+":"+direction.getText());
    22         }
    23     }
    24 
    25 }

    覆盖enum的方法

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

    switch语句中的enum

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

     1 package com;
     2 
     3 /**
     4  * Created by JohnTsai on 15/10/23.
     5  */
     6 enum Signal {
     7     GREEN, YELLOW, RED
     8 }
     9 
    10 public class TrafficLight {
    11     Signal color = Signal.GREEN;
    12 
    13     public void change() {
    14         switch (color) {
    15             case RED:
    16                 color = Signal.GREEN;
    17                 break;
    18             case GREEN:
    19                 color = Signal.YELLOW;
    20                 break;
    21             case YELLOW:
    22                 color = Signal.RED;
    23                 break;
    24         }
    25     }
    26 
    27     @Override
    28     public String toString() {
    29         return "traffic light is" + color;
    30     }
    31 
    32     public static void main(String[] args) {
    33         TrafficLight light = new TrafficLight();
    34         for (int i = 0; i < 10; i++) {
    35             System.out.println(light);
    36             light.change();
    37         }
    38     }
    39 }

    values()的神秘之处

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

     1 package com;
     2 
     3 import java.lang.reflect.Method;
     4 import java.lang.reflect.Type;
     5 import java.util.Set;
     6 import java.util.TreeSet;
     7 
     8 /**
     9  * Created by JohnTsai on 15/10/25.
    10  */
    11 enum Explore{
    12     HERE,THERE
    13 }
    14 public class Reflection {
    15     public static Set<String> analyse(Class<?> enumClass){
    16         println("Analyzing begin:");
    17         println("Interfaces:");
    18         for(Type t:enumClass.getGenericInterfaces()){
    19             print(t.toString());
    20         }
    21         println("Base:"+enumClass.getSuperclass());
    22         println("Methods:");
    23         Set<String> methods = new TreeSet<>();
    24         for(Method m:enumClass.getMethods()){
    25             methods.add(m.getName());
    26         }
    27         println(methods.toString());
    28         return methods;
    29     }
    30 
    31 
    32     public static void println(String s){
    33         System.out.println(s);
    34     }
    35 
    36     public static void print(String s){
    37         System.out.print(s);
    38     }
    39 
    40     public static void main(String[] args) {
    41         Set<String> exploreMethods = analyse(Explore.class);
    42         Set<String> enumMethods = analyse(Enum.class);
    43         println("Explore containsAll(Enum)?"+exploreMethods.containsAll(enumMethods));
    44         println("Explore removeAll(Enum)"+exploreMethods.removeAll(enumMethods));
    45 
    46         println(exploreMethods.toString());
    47     }
    48 }
    49 
    50 
    51 //output:
    52 /**Analyzing begin:
    53 Interfaces:
    54 Base:class java.lang.Enum
    55 Methods:
    56 [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait]
    57 Analyzing begin:
    58 Interfaces:
    59 java.lang.Comparable<E>interface java.io.SerializableBase:class java.lang.Object
    60 Methods:
    61 [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait]
    62 Explore containsAll(Enum)?true
    63 Explore removeAll(Enum)true
    64 [values]
    65 */

    反编译之前的枚举类型Gender

    javac Gender.class
    javap Gender
    Compiled from "Gender.java"
    public final class com.Gender extends java.lang.Enum<com.Gender> {
      public static final com.Gender MALE;
      public static final com.Gender FEMALE;
      public static com.Gender[] values();
      public static com.Gender valueOf(java.lang.String);
      static {};
    }

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

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

     1 package com;
     2 
     3 /**
     4  * Created by JohnTsai on 15/10/25.
     5  */
     6 public class UpcastEnum {
     7     public static void main(String[] args) {
     8         Gender[] values = Gender.values();
     9         Enum e = Gender.MALE;
    10 //        e.values();No values() in Enum
    11         for (Enum en : e.getClass().getEnumConstants()) {
    12             System.out.println(en);
    13         }
    14     }
    15 }
    16 
    17 //output
    18 /**
    19 MALE
    20 FEMALE
    21 */

    实现,而非继承

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

    1  System.out.println("Gender's super class:"+Gender.class.getSuperclass());
    2 //output:
    3 //Gender's super class:class java.lang.Enum

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

    转载:http://www.cnblogs.com/JohnTsai/p/4903125.html

     
  • 相关阅读:
    二维几何前置知识
    点分治学习笔记
    $fhq-treap$学习笔记
    对拍使用方法
    2021.2.18-2021.5.18 三个月后端开发实习的学习路径
    蓝桥杯常考算法 + 知识点
    Linux
    Linux
    Intern Day112
    Linux上编译运行C/C++程序
  • 原文地址:https://www.cnblogs.com/benchao/p/5273125.html
Copyright © 2020-2023  润新知