• Java编程思想学习笔记——枚举类型


    前言

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

    正文

    基本enum特性

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

    public class TestEnum {
        public static void main(String[] args) {
            Fruit[] values = Fruit.values();
            for (Fruit fruit : values) {
                System.out.println(fruit);
                printEnum(fruit);
            }
        }
    
        public enum Fruit {
            APPLE, ORANGE, WATERMELON
        }
    
       public static void printEnum(Fruit fruit) {
            //顺序
            System.out.println(fruit + " ordinal:" + fruit.ordinal());
            //比较(ordinal值)
            System.out.println("compare to apple" + fruit.compareTo(Fruit.APPLE));
            //==
            System.out.println(fruit == Fruit.ORANGE);
            //获取所属的enum类
            System.out.println(fruit.getDeclaringClass());
            //获取名字
            System.out.println(fruit.name());
        }
    }
    
    //output
    /**
    APPLE
    ORANGE
    WATERMELON
    */
    
    /**
    APPLE ordinal:0
    compare to apple0
    false
    class com.TestEnum$Fruit
    APPLE
    ORANGE ordinal:1
    compare to apple1
    true
    class com.TestEnum$Fruit
    ORANGE
    WATERMELON ordinal:2
    compare to apple2
    false
    class com.TestEnum$Fruit
    WATERMELON
    */
    

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

    将静态导入用于enum

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

    package com;
    
    import static com.Gender.*;
    
    /**
     * Created by JohnTsai on 15/10/22.
     */
    public class TestStaticImport {
        Gender gender;
    
        public static void main(String[] args) {
            System.out.println(new TestStaticImport(MALE));
            System.out.println(new TestStaticImport(FEMALE));
        }
    
        public TestStaticImport(Gender gender) {
            this.gender = gender;
        }
    
        @Override
        public String toString() {
            return "GENDER is" + this.gender;
        }
    }
    
    

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

    package com;
    
    /**
     * Created by JohnTsai on 15/10/23.
     */
    public enum Direction {
        //最先定义enum实例
        WEST("this is west"),EAST("this is east"),NORTH("this is north"),SOUTH("this is south");
        //要定义自己的方法,需在定义的enum实例后加分号
    
        private String text;
        private Direction(String text){
            this.text = text;
        }
        public String getText(){
            return this.text;
        }
    
        public static void main(String[] args) {
            for(Direction direction:Direction.values()){
                System.out.println(direction+":"+direction.getText());
            }
        }
    
    }
    
    

    覆盖enum的方法

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

    switch语句中的enum

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

    package com;
    
    /**
     * Created by JohnTsai on 15/10/23.
     */
    enum Signal {
        GREEN, YELLOW, RED
    }
    
    public class TrafficLight {
        Signal color = Signal.GREEN;
    
        public void change() {
            switch (color) {
                case RED:
                    color = Signal.GREEN;
                    break;
                case GREEN:
                    color = Signal.YELLOW;
                    break;
                case YELLOW:
                    color = Signal.RED;
                    break;
            }
        }
    
        @Override
        public String toString() {
            return "traffic light is" + color;
        }
    
        public static void main(String[] args) {
            TrafficLight light = new TrafficLight();
            for (int i = 0; i < 10; i++) {
                System.out.println(light);
                light.change();
            }
        }
    }
    
    

    values()的神秘之处

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

    package com;
    
    import java.lang.reflect.Method;
    import java.lang.reflect.Type;
    import java.util.Set;
    import java.util.TreeSet;
    
    /**
     * Created by JohnTsai on 15/10/25.
     */
    enum Explore{
        HERE,THERE
    }
    public class Reflection {
        public static Set<String> analyse(Class<?> enumClass){
            println("Analyzing begin:");
            println("Interfaces:");
            for(Type t:enumClass.getGenericInterfaces()){
                print(t.toString());
            }
            println("Base:"+enumClass.getSuperclass());
            println("Methods:");
            Set<String> methods = new TreeSet<>();
            for(Method m:enumClass.getMethods()){
                methods.add(m.getName());
            }
            println(methods.toString());
            return methods;
        }
    
    
        public static void println(String s){
            System.out.println(s);
        }
    
        public static void print(String s){
            System.out.print(s);
        }
    
        public static void main(String[] args) {
            Set<String> exploreMethods = analyse(Explore.class);
            Set<String> enumMethods = analyse(Enum.class);
            println("Explore containsAll(Enum)?"+exploreMethods.containsAll(enumMethods));
            println("Explore removeAll(Enum)"+exploreMethods.removeAll(enumMethods));
    
            println(exploreMethods.toString());
        }
    }
    
    
    //output:
    /**Analyzing begin:
    Interfaces:
    Base:class java.lang.Enum
    Methods:
    [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, values, wait]
    Analyzing begin:
    Interfaces:
    java.lang.Comparable<E>interface java.io.SerializableBase:class java.lang.Object
    Methods:
    [compareTo, equals, getClass, getDeclaringClass, hashCode, name, notify, notifyAll, ordinal, toString, valueOf, wait]
    Explore containsAll(Enum)?true
    Explore removeAll(Enum)true
    [values]
    */
    

    反编译之前的枚举类型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实例。

    package com;
    
    /**
     * Created by JohnTsai on 15/10/25.
     */
    public class UpcastEnum {
        public static void main(String[] args) {
            Gender[] values = Gender.values();
            Enum e = Gender.MALE;
    //        e.values();No values() in Enum
            for (Enum en : e.getClass().getEnumConstants()) {
                System.out.println(en);
            }
        }
    }
    
    //output
    /**
    MALE
    FEMALE
    */
    

    实现,而非继承

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

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

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

  • 相关阅读:
    0Day – 2011.01.26
    JQuery_PHP 开始新的旅途
    0Day – 2011.01.25
    0Day – 2011.02.04
    Delphi 必须的一致.
    0Day – 2011.01.28
    0Day – 2011.02.23[From B4A]
    足球 看球悲惨的回忆.
    Delphi – EurekaLog6.1.01Ent下载地址
    ubuntu 拨号
  • 原文地址:https://www.cnblogs.com/JohnTsai/p/4903125.html
Copyright © 2020-2023  润新知