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

 
时间: 2024-08-10 10:42:26

Java编程思想学习(十四) 枚举的相关文章

Java编程思想学习(十六) 并发编程

线程是进程中一个任务控制流序列,由于进程的创建和销毁需要销毁大量的资源,而多个线程之间可以共享进程数据,因此多线程是并发编程的基础. 多核心CPU可以真正实现多个任务并行执行,单核心CPU程序其实不是真正的并行运行,而是通过时间片切换来执行,由于时间片切换频繁,使用者感觉程序是在并行运行.单核心CPU中通过时间片切换执行多线程任务时,虽然需要保存线程上下文,但是由于不会被阻塞的线程所阻塞,因此相比单任务还是大大提高了程序运行效率. 1.线程的状态和切换: 线程的7种状态及其切换图如下: 2.多线

Java编程思想学习(十二) 数组和容器

一.数组 1).数组的多种初始化方式 下面总结了初始化数组的多种方式,以及如何对指向数组的引用赋值,使其指向另一个数组对象.值得注意的是:对象数组和普通数组的各种操作基本上都是一样的:要说有什么不同的话就是对象数组默认值为null,而基本数组视本身情况而定. 1 package lkl; 2 3 import java.util.Arrays; 4 5 ///下面演示了数组的初始化 6 //包括对象数组和普通数组 7 class Base{ 8 private static long count

Java编程思想学习第一天

今天开始正式学习Java编程思想,把遇到的一些比较经典的语句记录下来,作为自己学习的一份成果! 一. 面向对象的基本特性: 第一:万物皆为对象        第二:程序是对象的集合,他们通过发送消息来告知彼此所要做的   第三:每个对象都有自己的由其他对象所构成的存储   第四:每个对象都拥有其类型   第五:某一特定类型的所有对象都可以接收同样的消息   对象具有状态.行为和标识 二. 每个对象都提供服务      1. 将对象想象为一个服务提供者,程序本身将向用户提供服务 2. 将对象想象为

【Java编程思想--学习笔记(一)】访问控制-包

Java编程思想–学习笔记(一) 访问控制(或隐藏具体实现)与"最初的实现并不恰当"有关. 1.包:库单元 我们之所以要导入包,就是要提供一个管理名字的空间机制. 每个java文件只能有一个public类.其他私有类为主public·类提供支持. 1.1 代码组织 与编译型语言不同,java可运行程序是一组可以打包并压缩成java文档文件(JAR,使用Java的jar文档生成器)的.class文件. 使用package和import关键字,使得不会出现名称冲突问题. 注意:java包的

JAVA编程思想(第四版)学习笔记----4.8 switch(知识点已更新)

switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) { case integral-value1: statement; break; case integral-value12: statement; break; default: statement; } 其中integral-selector(整数选择因子)是一个能产生整数值的表达式.并且说

【java编程思想--学习笔记(四)】对象导论

写这篇博客的前言: 长话短说,我希望通过阅读<java编程思想>来使我的代码 简洁可用 . 目的的层次不同,首先具体的目标是,了解Java的特性和巩固Java的基础. 更抽象的目的如下: 1.期待以巩固基础的方式,使代码优美,简洁,高效. 2.使自己写的模块能够开放适度,好用. 3.形成一种对代码是否优美的审美观. 于是<Java编程思想>第一章 对象导论 由此开始. 1.1 抽象过程 java 相对于命令式语言的优势在于只针对于待解问题建模.后者所做的主要抽象要求所做问题基于计算

java编程思想学习(1)

Smalltalk 这是第一种成功的面向对象程序设计语言,也是Java 的基础语言.Smalltalk (java的基础语言)的五大基本特征: (1) 所有东西都是对象.可将对象想象成一种新型变量:它保存着数据,但可要求它对自身进行操作.理论上讲,可从要解决的问题身上提出所有概念性的组件,然后在程序中将其表达为一个对象. (2) 程序是一大堆对象的组合:通过消息传递,各对象知道自己该做些什么.为了向对象发出请求,需向那个对象"发送一条消息".更具体地讲,可将消息想象为一个调用请求,它调

JAVA编程思想学习笔记——第一章 对象导论

搞了一年多java,野路子出身,发现java基础这块还是相当的薄弱!故决定学习<Java编程思想>这本书.在此把学习的知识点记录下! 面向对象的五大特性 1.万物皆为对象 2.程序是对象的集合,它们通过发送消息来告诉彼此所要做的 3.每个对象都由自己的由其它对象所构成的存储 4.每个对象都拥有其类型 5.某一特定类型的所有对象都可以接收同样的信息  单根继承结构 所有的类都继承自单一的基类,Object.在单根集成结构中的所有对象都具有一个公用接口,所以他们归根到底都是相同的基本类型.单根集成

[Java编程思想-学习笔记]第3章 操作符

3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("Hello, world"); 我们都会感觉太冗长了,能不能简单一些呢?静态导入可以省略掉System,就像这样 import static java.lang.System.*; public class Hello { public static void main(String[] args) {