关键字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

 

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

  1. Java编程思想之十四 类型信息

    第十四章 类型信息 运行时类型信息使得你可以在程序运行时发现和使用类型信息 14.1 为什么需要RTTI 面向对象编程中基本的目的是:让代码只操作对基类的引用. 多态: import java.uti ...

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

    线程是进程中一个任务控制流序列,由于进程的创建和销毁需要销毁大量的资源,而多个线程之间可以共享进程数据,因此多线程是并发编程的基础. 多核心CPU可以真正实现多个任务并行执行,单核心CPU程序其实不是 ...

  3. Java编程思想学习(十) 正则表达式

    正则表达式是一种强大的文本处理工具,使用正则表达式我们可以以编程的方法,构造复杂的文本模式,并且对输入的字符串进行搜索.在我看来,所谓正则表达式就是我们自己定义一些规则,然后就可以验证输入的字符串是不 ...

  4. Java编程思想学习(十五) 注解

    注解Annotation又叫元数据,是JDK5中引入的一种以通用格式为程序提供配置信息的方式.使用注解Annotation可以使元数据写在程序源码中,使得代码看起来简洁,同时编译器也提供了对注解Ann ...

  5. Java编程思想之十八 枚举类型

    关键字enum可以将一组具名的值的有限集合创建为一种新的类型, 而这些具名的值可以作为常规的程序组件使用.这是一种非常有用的功能. 18.1 基本enum特性 创建enum时,编译器会为你生成一个相关 ...

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

    一.数组 1).数组的多种初始化方式 下面总结了初始化数组的多种方式,以及如何对指向数组的引用赋值,使其指向另一个数组对象.值得注意的是:对象数组和普通数组的各种操作基本上都是一样的:要说有什么不同的 ...

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

    switch语句和if-else语句不同,switch语句可以有多个可能的执行路径.在第四版java编程思想介绍switch语句的语法格式时写到: switch (integral-selector) ...

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

    3.1  更简单的打印语句 学习编程语言的通许遇到的第一个程序无非打印"Hello, world"了,然而在Java中要写成 System.out.println("He ...

  9. Java编程思想学习(八) 内部类

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类的定义是简单的,但是它的语法确实很是复杂,让人不是很好理解.下面就内部类做一个小结. 一.内部类的分类 总的来讲内部类分为普通内部类,匿 ...

随机推荐

  1. 2014 Super Training #1 B Fix 状压DP

    原题: HDU 3362 http://acm.hdu.edu.cn/showproblem.php?pid=3362 开始准备贪心搞,结果发现太难了,一直都没做出来.后来才知道要用状压DP. 题意: ...

  2. 阿里巴巴Druid数据源,史上最强的数据源,没有之一

    目前常用的数据源主要有c3p0.dbcp.proxool.druid,先来说说他们Spring 推荐使用dbcp:Hibernate 推荐使用c3p0和proxool1. DBCP:apacheDBC ...

  3. [汇编] 002基础知识-CPU和寄存器

    CPU是什么 当然这里的内存不仅仅指电脑上的内存,例如:我的金士顿8G内存,七彩虹1G独显,在这里来说,显卡也是有内存的(寄存器) CPU如何控制其它部件的? 问题:CPU是如何和电脑主机中其它芯片有 ...

  4. 关于OAuth2.0的文章收集

    http://blog.csdn.net/seccloud/article/details/8192707

  5. Android Handler处理机制 ( 三 ) ——Handler,Message,Looper,MessageQueue

    在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长时间的任务后做出相应的通知 handler基本使用: 在主线程中,使用handler很简单,new一个Handle ...

  6. WPF登陆窗口、主窗口切换问题

    代码 MainWindow mwin = new MainWindow(); Application.Current.MainWindow = mwin; this.Close(); mwin.Sho ...

  7. C# 将透明图片的非透明区域转换成Region

    以下代码实现将一张带透明度的png图片的非透明部分转换成Region输出 /// <summary> /// 根据图片得到一个图片非透明部分的区域 /// </summary> ...

  8. no.1

    #import requests import urllib import bs4 try: html=urllib.urlopen('http://anyun.org') except HTTPer ...

  9. ant exec

    http://ant.apache.org/manual/Tasks/exec.html Exec Description Executes a system command. When the os ...

  10. vim环境设置和自动对齐

    只要在 /etc/vimrc中加上这两句就行了set autoindentset smartindent------------------------------------------------ ...