简单看看java之枚举
枚举类这个类用的比较少,对这个不怎么熟悉,最近看源码刚好可以好好了解一下,那么,枚举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之枚举的更多相关文章
- 简单认识java enum枚举
什么是枚举 枚举是java5中新增的特性,他是一个特殊的数据类型,他的特殊性在于他既是一种类类型,又比类类型多了安全性,简洁性,便捷性.java枚举类型是功能十分强大齐全的类,功能比其他语言中的对等物 ...
- 关于Java中枚举Enum的深入剖析
在编程语言中我们,都会接触到枚举类型,通常我们进行有穷的列举来实现一些限定.Java也不例外.Java中的枚举类型为Enum,本文将对枚举进行一些比较深入的剖析. 什么是Enum Enum是自Java ...
- 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)
写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能 ...
- (转)简单介绍java Enumeration
简单介绍java Enumeration 分类: java技术备份 java数据结构objectstringclass存储 Enumeration接口 Enumeration接口本身不是一个数据结构 ...
- 深度分析Java的枚举类型—-枚举的线程安全性及序列化问题
原文:深度分析Java的枚举类型--枚举的线程安全性及序列化问题 枚举是如何保证线程安全的 要想看源码,首先得有一个类吧,那么枚举类型到底是什么类呢?是enum吗?答案很明显不是,enum就和clas ...
- Java enum枚举类型
java的枚举类型详解: 简单示例: public enum Color{ RED,BLUE,BLACK,YELLOW,GREEN } 复杂示例(带自定义构造方法与类型) public enum En ...
- (转)java enum枚举
转载自: 原理:http://singleant.iteye.com/blog/686349 应用:http://www.cnblogs.com/happyPawpaw/archive/2013/04 ...
- Java基础—枚举
定义 枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示. 为什么要用枚举 在java语言中还没有引入枚举类型之前,表示枚 ...
- Java Enum枚举的用法(转)
说明:Java的枚举比dotnet的枚举好用,至少支持的方式有很多. 用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以 ...
随机推荐
- C++中的模板编程
一,函数模板 1.函数模板的概念 C++中提供了函数模板,所谓函数模板,实际上是建立一个通用函数,其函数的返回值类型和函数的参数类型不具体指定,用一个虚拟的类型来表示.这个通用函数就被称为函数的模板. ...
- 在Android手机上学习socket程序
我们都知道Android手机是基于Linux系统的,在没有Linux环境,但是想学习socket编程的同学可以在Android手机中试试,利用ndk编译可执行文件在Android手机中运行.不同于动态 ...
- WPF 画线动画效果实现
原文:WPF 画线动画效果实现 弄了将近三天才搞定的,真是艰辛的实现. 看了很多博客,都太高深了,而且想要实现的功能都太强大了,结果基础部分一直实现不了,郁闷啊~ 千辛万苦终于找到了一个Demo,打开 ...
- Kubernetes使用集群联邦实现多集群管理
Kubernetes在1.3版本之后,增加了“集群联邦”Federation的功能.这个功能使企业能够快速有效的.低成本的跨区跨域.甚至在不同的云平台上运行集群.这个功能可以按照地理位置创建一个复制机 ...
- VisualStateManager
管理控件状态和管理控件状态的转换逻辑 <Window.Resources> <Style TargetType="Button" x:Key="Anim ...
- C++调用Python浅析
环境 VS2005Python2.5.4 Windows XP SP3 简述 一般开发过游戏的都知道Lua和C++可以很好的结合在一起,取长补短,把Lua脚本当成类似动态链接库来使用,很好的利用了脚本 ...
- sqlserver检查sql执行时间
set statistics profile onset statistics io onset statistics time onGO select * from mytable; goset s ...
- window 10 64bit Tortoise SVN 图标状态显示不正常
https://www.cnblogs.com/lzpong/p/6187366.html 根据以上帖子处理 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows ...
- dotnet core 跨平台编译发布
vs2017 建立的项目,在项目目录 ,执行 dotnet publish -r ubuntu.15.04-x64 dotnet publish -r linux-x64 dotnet publish ...
- 超详细SQL SERVER 2016跨网段和局域网发布订阅配置图解和常见问题
原文:超详细SQL SERVER 2016跨网段和局域网发布订阅配置图解和常见问题 转载标明出处:http://blog.csdn.net/u012861467 前方高能,要有点耐心,图片较多,注意在 ...