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时,可以同时实现一个或多个接口。

原文地址:http://www.cnblogs.com/JohnTsai/p/4903125.html
相关文章
|
27天前
|
存储 安全 Java
小白聊《JAVA编程思想》-一切都是对象(一)
小白聊《JAVA编程思想》-一切都是对象(一)
13 0
|
8天前
|
安全 Java
Java进阶之枚举
【7月更文挑战第11天】Java枚举是Java 5引入的特性,用于定义固定常量集合,如星期。枚举是继承自`java.lang.Enum`的特殊类,编译后成为final类,每个枚举值是静态final实例。定义枚举用`enum`关键字,如`public enum Weekday {MONDAY, TUESDAY, ...}`。枚举可包含方法和变量,能实现接口但不能继承其他类。例如,`Weekday`枚举可实现`Describe`接口,提供`describe()`方法。在实际应用中,枚举常用于表示如响应状态等固定选项,便于类型安全和代码阅读。
22 8
|
28天前
|
Java
Java编程思想(面向对象)第四版PDF分享
探索《Java编程思想》第四版,理解Java不仅是特性集合,更是解决问题的强大工具。本书深入设计层面,构建编程思维模型,助你逐步精通Java。[阅读更多](https://zhangfeidezhu.com/?p=355) ![Java编程思想](https://ucc.alicdn.com/pic/developer-ecology/nrw3f3oqlpmag_c8ff959a921545f1bbabcefd37f029cf.png)
28 1
Java编程思想(面向对象)第四版PDF分享
|
24天前
|
设计模式 安全 Oracle
Java学习笔记:从入门到精通
Java学习笔记:从入门到精通
|
26天前
|
机器学习/深度学习 Java 关系型数据库
程序员必知:关于高淇JAVA中SORM总结学习笔记详细个人解释
程序员必知:关于高淇JAVA中SORM总结学习笔记详细个人解释
18 2
|
19天前
|
Java
Java中的枚举类型详解
Java中的枚举类型详解
|
22天前
|
Java
Java中的枚举类型详解:应用与最佳实践
Java中的枚举类型详解:应用与最佳实践
|
26天前
|
机器学习/深度学习 Java 关系型数据库
程序员必知:关于高淇JAVA中SORM总结学习笔记详细个人解释
程序员必知:关于高淇JAVA中SORM总结学习笔记详细个人解释
16 0
|
27天前
|
存储 Java 容器
小白聊《JAVA编程思想》-对象导论二
小白聊《JAVA编程思想》-对象导论二
11 0
|
27天前
|
存储 Java 数据安全/隐私保护
小白聊《JAVA编程思想》 对象导论一
小白聊《JAVA编程思想》 对象导论一
14 0