栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java枚举类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java枚举类

枚举

在编程的时候,需要一组概念。比如季节(春、夏、秋、冬),尺码(大、中、小),线程状态(New、Ready、Blocked...)。它们是确定的,有限的。这个时候我们就可以用枚举来抽象这组常量,使得编程更加切合语义化,统一化。程序员可以避免使用变量导致的一些不可预知的错误。

自定义枚举类

jdk5.0之前,人们使用枚举类,一定程度上解决了枚举常量的问题。在这之前程序员用int类型常量充当枚举实例,但可能出现错误。

punlic Class SIze {
	public final static int SAMLL = 0;
	public final static int MIDDLE = 1;
	public final static int BIG = 2;
}
switch(int num) {
case Size.SAMLL:
//do something...
break;
case Size.MIDDLE:
//do something...
break;
...
case 9:
//do something...
break;
...
default:
//do something...
break;
}

这样就有一个问题,所有程序员都可以创造一个int类型数据,所以可能出现错误。比如上面的switch中因为疏忽,case匹配中加入了一个不是枚举常量的常量。

case 9:
//do something...
break;
...

所以,用对象充当枚举实例不更好吗?一方面更符合面向对象编程思想,另一方面诸如switch匹配中绝对不会因为疏忽加入了不属于枚举的值!必要的时候还可以为这个枚举对象添加一些属性和方法,可以获得更多有用的信息,是不是更加利于编程?

punlic Class SIze {
	private final String desc;
	public final static SIzeSMALL = new SIze("小号");
	public final static SIze MIDDLE = new SIze("中号");
	public final static SIze BIG = new SIze("大号");
	private Size(String desc) {
		this.desc = desc;
	}
	public String getDesc() {
		return desc;
	}
}

enum来定义枚举类

这样定义枚举是不是已经很好了?但是Java开发者仍然不满足,他们觉得每一个枚举常量都要加public static final的修饰,所有方法和字段都要实现者手动添加,这样是不是冗余了?于是在JDK5.0时增添了新特性:①swicth语法中可以使用枚举类②开发者引入关键字enum,用户可以创造简洁的枚举类。

public enum  EnumTest {
    SPRING("春暖花开"),
    SUMMER("夏日炎炎"),
    AUTUMN("秋高气爽"),
    WINTER("半天雪地");
    private String desc;
    private EnumTest(String desc) {
        this.desc = desc;
    }
}

这个枚举类第一眼看去一定很奇怪!在jdk5.0之前这个类是这样定义的。

public class EnumTest {
    private String desc;
    private EnumTest(String desc) {
        this.desc = desc;
    }
    public static final EnumTest SPRING = new EnumTest("春暖花开");
    public static final EnumTest SUMMER = new EnumTest("夏日炎炎");
    public static final EnumTest AUTUMN = new EnumTest("秋高气爽");
    public static final EnumTest WINTER = new EnumTest("半天雪地");
}

注意siwch对枚举类的要求:

Switch(Season s) {
	
	case SPRING:
	//do something...     //正确的使用情况
}

java开发者规定:①enum实现的枚举类的所有对象必须声明在该类作用域的开头,使用逗号(,)分割多个枚举类对象②由于修饰符和构造器样式以及所属类都是重复的,所以只能声明枚举对象名,如果构造器带参数,可以这么声明:

SPRING("春暖花开");

相当于:

public sattic final Season SPRING = new SPRING("春暖花开");

③构造器一定是私有的,程序员可以省略不写。④该类不可被继承 ⑤该类如果是T,则继承于java.lang.Enum

如下反编译代码;
C:Users48266DesktopjavaSEoutproductionjavaSE>javap  EnumTest.class
Compiled from "EnumTest.java"
public final class EnumTest extends java.lang.Enum {
  public static final EnumTest SPRING;
  public static final EnumTest SUMMER;
  public static final EnumTest AUTUMN;
  public static final EnumTest WINTER;
  public static EnumTest[] values();
  public static EnumTest valueOf(java.lang.String);
  static {};
}

对于枚举类,编译器强制将类声明为final,继承java.lang.Enum

有几个方法很不错:
values(): 编译器生成,返回该枚举类所有枚举对象数组,索引按声明时排序
valueOf(String enumName): 编译器生成,返回该枚举名所有枚举对象,有受检异常
toString():Enum重写的,返回枚举对象名
父类的静态方法:
Values(Class,String):获取指定枚举类的枚举对象

答疑 为什么Enum声明为:
public class Enum>

因为Enum类实现了Comparable接口:

public interface Comparable {
	public int compareTo(T t);
}

这有什么问题呢?这样看:

public class Enum {

}

如果Enum类没有泛型,Comparable接口只能使用原始类型,是不是枚举类可以和任意类的对象进行比较了。编译的时候没问题,但是如何比较呢?难道在运行时调用getClass()方法,如果两者类型不一致的话抛出一个异常吗?
可是为何不在编译时就指出错误呢?这就要保证枚举类只能是继承类的泛型。
比如:

enum State extends Enum
enum Season extends Enum
...

如此必须对泛型限定:

public class Enum>

保证了,Enum泛型类必须是枚举本身类型的类。

enum Season extends Enum

Season 是不是继承了Enum类,其次继承的还是Enum,这样就保证了每一个实现类的泛型必须是它本身,解决了compareTo形参限定的问题!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/305556.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号