枚举类这个类用的比较少,对这个不怎么熟悉,最近看源码刚好可以好好了解一下,那么,枚举Enum是什么呢?在jdk中,Enum是一个抽象类下图所示,这就说明这个类是不能进行实例化的,那么我们应该怎么使用呢?

1.枚举类的基本使用

  简单的使用一下(随便借用的一个栗子),我们可以直接把枚举类当作一个常量一样来使用这个类,那么问题来了,下面的这个枚举类和上面说的那么Enum抽象类是什么关系呢?

  肯定是继承啊,这里很像Cglib动态代理,但肯定不是代理。。。反正下面这个类经过编译,就会编译出两个字节码文件,一个是TestEnum类。另外一个就是Week类(这个类自动继承Enum抽象类);

public class TestEnum{

    public static void main(String[] args) {
System.out.println(Week.MON);
}
}
//这个枚举也可以放在TestEnum里面,充当一个静态内部类
enum Week{
MON,TUE,WED,THU,FRI,SAT,SUN
}

  

  我们可以反编译一下看看Week类中到底是些什么东西;

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: TestEnum.java //自动的将枚举类Week继承Enum
final class Week extends Enum{ public static final Week MON;
public static final Week TUE;
public static final Week WED;
public static final Week THU;
public static final Week FRI;
public static final Week SAT;
public static final Week SUN;
private static final Week $VALUES[]; //静态代码块中会实例化七个对象和一个Week数组,用于存放这些实例化对象
static {
MON = new Week("MON", 0);
TUE = new Week("TUE", 1);
WED = new Week("WED", 2);
THU = new Week("THU", 3);
FRI = new Week("FRI", 4);
SAT = new Week("SAT", 5);
SUN = new Week("SUN", 6);
$VALUES = (new Week[] {
MON, TUE, WED, THU, FRI, SAT, SUN
});
}
//构造器
private Week(String s, int i){
super(s, i);
} //生成静态方法values,克隆一份数组,也就是调用这个方法之后就会返回一份包括枚举类中所有实例的数组
public static Week[] values(){
return (Week[])$VALUES.clone();
}
//生成静态方法valueOf,通过指定一个枚举类型和实例的名称(字符串),可以转化为一个该枚举类型的对象
public static Week valueOf(String s){
return (Week)Enum.valueOf(Week, s);
} }

  可以看到Enum虽然我们用的时候是用Enum来声明的,但是实际上就是一个类,是为了让我们用起来方便简洁,才这样设计的(虽然我还是觉得枚举很怪。。。);

2.看看Enum抽象类

  我们发现生成的Week类中构造器会调用父类的构造器,其中i表示每个实例在数组中的位置,还有values和valueof方法也会调用父类的方法,我们看看父类所有方法实现,然后再回头看看就清楚了;

package java.lang;

import java.io.Serializable;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException; //这是一个抽象类,只能被继承
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
//枚举类中的实例名称
private final String name; //获取实例名称
public final String name() {
return name;
} //该实例在实例数组中的位置
private final int ordinal; //获取该实例所在位置
public final int ordinal() {
return ordinal;
} //此构造器只能由子类自己调用,我们是不能调用,看到子类Week中的构造器中的super(s, i);
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
} //输出实例名称
public String toString() {
return name;
} //重写equal方法和hashcode方法,由于枚举类中都是对象,那么比较的肯定就是引用是不是一样了
public final boolean equals(Object other) {
return this==other;
}
public final int hashCode() {
return super.hashCode();
} //克隆,这里会直接报错,子类中调用的是Object中的clone方法
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
} //比较一个枚举类中实例名称的前后顺序
public final int compareTo(E o) {
Enum other = (Enum)o;
Enum self = this;
if (self.getClass() != other.getClass() &&
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
} //获取枚举实例的Class对象和父类的Class对象,然后判断是不是一个对象,我也不知道干嘛用的
public final Class<E> getDeclaringClass() {
Class clazz = getClass();
Class zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? clazz : zuper;
} //这个方法就是当存在多个枚举类的时候,每个枚举类都有各自对应的多个实例,这个方法就是将
//根据对应的枚举类的类型,该枚举类中的实例名称,以此来返回该枚举类型的对象
public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException(
"No enum constant " + enumType.getCanonicalName() + "." + name);
} //最没用的方法,Object中也有
protected final void finalize() { } //这两个方法不知道干嘛用的。。。都会直接抛异常
private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
}

  这个抽象类方法也不是很多,很容易,现在再来看看枚举类应该就很容易了;

   我们理一下思路:当我们在一个平常的类中使用了枚举类的话,而且这个枚举类中定义了很多个实例,那么在使用的时候就会将枚举类拿出来和类分开编译,这个枚举类中的多个实例(这里每个实例都有自己的数组下标)都给实例化出来,并且放到一个实例数组中;其中每个枚举类都会自动继承Enum这个抽象类,我们可以根据对应的枚举类来获取每个实例的对象,当然枚举类可能也有多个,那么也可以根据Enum这个抽象类来获取对应枚举类中的实例,并转化为该枚举类的类型返回。。。

  原理就这么多吧!下面来看看枚举类的一些其他用法;

3.枚举类的简单用法

  首先,枚举类可以实现接口:

public interface MyEnum {
public void say();
} //实现接口
public enum TestEnum implements MyEnum{
//注意,
MON, TUE, WED, THU, FRI, SAT, SUN; @Override
public void say() {
System.out.println("實現接口--------say");
} public static void main(String[] args) {
TestEnum.MON.say();
} }

  

  然后在枚举类中还能有一些属性,以及set/get方法;

package com.wyq.test;

public enum TestEnum implements MyEnum{
//注意,这里最后要加分号
MON("mon",12), TUE("tue",12), WED("wed",12), THU("thu",12); private String name;
private Integer age; private TestEnum(String name, Integer age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} @Override
public void say() {
System.out.println("实现接口--------say");
} public static void main(String[] args) {
System.out.println(TestEnum.MON.getName()+TestEnum.MON.getAge()); } }

4.总结

  反正枚举类用的比较少,我就在那个单例模式下用过(天生的单例),至于其他的地方暂时用的比较少,不过当需要用的时候我们一定要会用啊;

  简单的看了看源码之后,其实再回头看看枚举类,其实就跟我们平常用的类差不多,不可以继承(因为默认已经继承了Enum类了),可以有自己的属性,方法,也可以覆盖父类的方法(可以自己试试),就跟平常类一样的使用!就是写法略怪,习惯就好!!!

  话说昨天下午弄了好久,终于被我找到在博客园配置出了血小板看板娘了,哈哈哈,我现在声明一句:血小板就是我老婆,不接受反驳!嘿嘿嘿@_@

简单看看java之枚举的更多相关文章

  1. 简单认识java enum枚举

    什么是枚举 枚举是java5中新增的特性,他是一个特殊的数据类型,他的特殊性在于他既是一种类类型,又比类类型多了安全性,简洁性,便捷性.java枚举类型是功能十分强大齐全的类,功能比其他语言中的对等物 ...

  2. 关于Java中枚举Enum的深入剖析

    在编程语言中我们,都会接触到枚举类型,通常我们进行有穷的列举来实现一些限定.Java也不例外.Java中的枚举类型为Enum,本文将对枚举进行一些比较深入的剖析. 什么是Enum Enum是自Java ...

  3. 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)

    写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能 ...

  4. (转)简单介绍java Enumeration

    简单介绍java Enumeration 分类: java技术备份 java数据结构objectstringclass存储 Enumeration接口  Enumeration接口本身不是一个数据结构 ...

  5. 深度分析Java的枚举类型—-枚举的线程安全性及序列化问题

    原文:深度分析Java的枚举类型--枚举的线程安全性及序列化问题 枚举是如何保证线程安全的 要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和clas ...

  6. Java enum枚举类型

    java的枚举类型详解: 简单示例: public enum Color{ RED,BLUE,BLACK,YELLOW,GREEN } 复杂示例(带自定义构造方法与类型) public enum En ...

  7. (转)java enum枚举

    转载自: 原理:http://singleant.iteye.com/blog/686349 应用:http://www.cnblogs.com/happyPawpaw/archive/2013/04 ...

  8. Java基础—枚举

    定义 枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示. 为什么要用枚举 在java语言中还没有引入枚举类型之前,表示枚 ...

  9. Java Enum枚举的用法(转)

    说明:Java的枚举比dotnet的枚举好用,至少支持的方式有很多. 用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以 ...

随机推荐

  1. Method and apparatus for establishing IEEE 1588 clock synchronization across a network element comprising first and second cooperating smart interface converters wrapping the network element

    Apparatus for making legacy network elements transparent to IEEE 1588 Precision Time Protocol operat ...

  2. linux 静态库和动态库(共享库)的制作与使用(注意覆盖问题)

    一.linux操作系统支持的函数库分支 静态库:libxxx.a,在编译时就将库编译进可执行程序 优点:程序的运行环境中不需要外部的函数库 缺点:可执行程序大 动态库:又称共享库,libxxx.so, ...

  3. POCO文档翻译:POCO C++库入门指南

    内容目录 介绍 Foundation库 XML库 Util库 Net库 将这些东西组合到一起 介绍 POCO C++库是一组开源C++类库的集合,它们简化及加速了用C++来开发以网络功能为核心的可移植 ...

  4. python 教程 第十六章、 正则表达式

    第十六章. 正则表达式 1)    匹配多个表达式 记号  re1|re2 说明  匹配正则表达式re1或re2 举例  foo|bar  匹配  foo, bar 记号  {N} 说明  匹配前面出 ...

  5. ListView、TreeView和DataGrid。

    原文:ListView.TreeView和DataGrid. 1.ListView. ListView继承自简单的没有特色的ListBox,并使用View属性进行扩展.增加了对基于列显示的支持,并增加 ...

  6. SEED缓冲区溢出实验笔记——Return_to_libc

    参考:http://www.cis.syr.edu/~wedu/seed/Labs_12.04/Software/Return_to_libc/    http://drops.wooyun.org/ ...

  7. SQLite Expert Professional 打开加密SQLite数据库

    原文 SQLite Expert Professional 打开加密数据库 (已修改) 版本:sqlite expert professional 4.2.0.739 (x86) 目的:用SQLite ...

  8. Android零基础入门第49节:AdapterViewFlipper图片轮播

    原文:Android零基础入门第49节:AdapterViewFlipper图片轮播 上一期学习了ExpandableListView的使用,你已经掌握了吗?本期开始学习AdapterViewFilp ...

  9. The specified type member 'IsLock' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

    var query = from C in objDb.GetDb<A>() join a in objDb.GetDb<B>().Where(m => m.Comput ...

  10. 给 Web 开发人员推荐的通用独立 UI 组件(二)

    现代 Web 开发在将体验和功能做到极致的同时,对于美观的追求也越来越高.在推荐完图形库之后,再来推荐一些精品的独立 UI 组件.这些组件可组合在一起,形成美观而交互强大的 Web UI . 给 We ...