`
Now7!
  • 浏览: 7785 次
  • 性别: Icon_minigender_1
  • 来自: 济南
文章分类
社区版块
存档分类
最新评论

Java中枚举的一些问题

阅读更多

 

1.枚举类型是做了特殊限制的类,在Class文件格式中的变化是添加了值为0x4000的属性标记ACC_ENUM,同时添加的还有值为0x2000的ACC_ANNOTATION。这些变化是[JVMS:99]之后的05年做出的,这里是对[JVMS:99]的官方修改说明


2.枚举类型不能由程序员来显式实例化,这来自使用枚举的初衷(即语义上不允许)。而语法上的不允许,则由如下4点保证:a.编译器强制其构制造函数一定是private修饰符,以保证其不被类外实例化。类内的实例化亦不被允许,实例化的尝试会导致编译器报错。b.继承自Enum的final修饰的clone()方法是固定写好了的。c.序列化技术队枚举做了特殊处理。d.反射中对枚举类型的实例化会得到运行时错误。翻译自[JLS:05],Page249。


3.试图为枚举类型的写finalize()方法将导致编译器错误,因为枚举常量永远不会被垃圾回收。翻译自[JLS:05],Page250。


4.任何枚举类型的(隐式)直接父类都是java.lang.Enum<E>,E是由程序员自己定义的枚举类型。可以注意到Enum类自身的声明:

 

public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable

除此以外,我们注意到其声明了以下方法(忽略从Object类继承来的众多方法):

 

 

Class<E>	getDeclaringClass();
// Returns the Class object corresponding to this enum constant's enum type.

String	name();
// Returns the name of this enum constant, exactly as declared in its enum declaration.

int	ordinal();
// Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial constant is assigned an ordinal of zero).

static <T extends Enum<T>> T valueOf(Class<T> enumType, String name);
// Returns the enum constant of the specified enum type with the specified name.

 

参考自:[JDK API:05]


 5.自己定义的枚举类型E,编译器会为程序员生成以下方法,并且不允许程序员自己写一个方法签名相同的方法,从而保证了以下方法行为的正确:

 

public static E[] values();
public static E valueOf(String name);

 

而且,其方法实现及与Enum类之联系由如下示例说明:

 

public enum Season{
   SPRING,SUMMER, AUTUMN,WINTER;
}

 

 上述定义的枚举类Season实际被javac修改如下:

 

public enum Season extends Enum<Season> {

    public static final SPRING = new Season("SPRING", 0);
    public static final SUMMER = new Season("SUMMER", 1);
    public static final AUTUMN = new Season("AUTUMN", 2);
    public static final WINTER = new Season("WINTER", 3);
    /*synthetic*/ private static final Season[] $VALUES = new Season[]{Season.SPRING , Season.SUMMER , Season.AUTUMN , Season.WINTER };

    public static Season[] values() {
        return (Season[])$VALUES.clone();
    }

    public static Season valueOf(String name) {
        return (Season)Enum.valueOf(Season.class, name);
    }

    private Season(/*synthetic*/ String $enum$name, /*synthetic*/ int $enum$ordinal) {
        super($enum$name, $enum$ordinal);
    }
}

示例参考自How is values() implemented for Java 6 enums


6.switch语句对于枚举类型的支持在下面做了说明。对于这样的代码:

 

public class Test
{
	static enum Type
	{
		A, B;
	}

	public static void main(String[] args)
	{
		Type t = Type.valueOf(args[0]);
		switch (t)
		{
			case A:
				System.out.println("We've got A");
				break;
			case B:
				System.out.println("We've got B");
				break;
		}
	}
}

 将被javac改写为如下代码:

 

public class Test
{
	static enum Type
	{
		A, B;
	}

	private static int[] $SWITCH_TABLE$Test$Type;

	static int[] $SWITCH_TABLE$Test$Type()
	{
		if (Type.$SWITCH_TABLE$Test$Type != null)
			return $SWITCH_TABLE$Test$Type;
		else
		{
			int[] is = new int[Type.values().length];
			is[Type.A.ordinal()] = 1;
			is[Type.B.ordinal()] = 2;
			$SWITCH_TABLE$Test$Type = is;
			return is;
		}
	}

	public static void main(String[] args)
	{
		Type t = Type.valueOf(args[0]);
		int[] is = $SWITCH_TABLE$Test$Type();
		int i = is[t.ordinal()];
		switch (i)
		{
			case 1:
				System.out.println("We've got A");
				break;
			case 2:
				System.out.println("We've got B");
				break;
		}
	}
}

 其中我们需要注意两点:

a.既然字节码采用的是tableswitch,那直接用Type.ordinal()返回的0~n-1作为tableswitch的下界和上界似乎更合理。但是,因为switch语句中的case标签的顺序可以不按照ordinal()的顺序写出,而为了case中的具体语句(上例为输出"We've got A"和"We've got B")的顺序不变,所以采用了int[]类型的$SWITCH_TABLE$Test$Type作为中间过渡。有意思的是,javac为这个field和另一个method使用了相同的名称,不要看的迷迷糊糊,:)

b.虽然这里是final static的常量,但是在case标签里面却不能像我们使用其他常量那样使用全额限定名:Test.Type.A或者Test.Type.B,而必须简写为A或者B。注意,这不是一个错误或者失误,以后亦不会做出改变。这个是有意思的一个讨论原因请参考官方的回应

 

分享到:
评论

相关推荐

    java枚举实例代码

    Java枚举(enum)是Java语言中的一种特殊数据类型,用于定义一组有限的常量,这些常量在程序中作为固定的值使用。枚举在Java中被引入,目的是为了更好地管理和使用常量,提高代码的可读性和安全性。在本实例代码中,...

    java中枚举的使用

    枚举在Java中的使用不仅提高了代码的可读性和可维护性,还避免了传统常量类的一些潜在问题,如类型安全和非法实例化。 首先,我们来看枚举的基本定义。枚举类型的声明类似于类的声明,但用关键字`enum`开头。例如:...

    java enum 枚举 学习资料

    此外,枚举类中还可以声明一些普通的成员变量和方法。 4. toString() 方法 toString() 方法是枚举类中的一个重要方法,它用于显示枚举类元素的字符串表示形式。如果不覆盖这个方法,默认情况下将打印变量名。 5. ...

    说说Java中的枚举 转 可以了,够了 包括EnumSet(Map)

    这篇博客将深入探讨Java枚举的特性和使用方法,包括`EnumSet`和`EnumMap`这两个与枚举相关的数据结构。 首先,枚举定义的基本语法是`public enum EnumName {constant1, constant2, ...}`。每个枚举常量都是`...

    java 通过反射获取枚举类,及枚举类的值,枚举类枚举实例名

    枚举(Enumeration)是Java中的一个特殊类类型,用于定义一组常量。本项目"test-enum-demo-master"显然是一个用于演示如何通过反射来操作枚举类的示例。 首先,让我们理解枚举类的基本概念。枚举类在Java中用于定义...

    java枚举结果类、根据状态值获取枚举值

    java枚举结果类、根据状态值获取枚举值 Controller: /** 模块类型枚举 */ model.addAttribute("mType", ModuleTypeEnum.ModuleTypeShow()); ftl: value="${mType.key}:${mType.value}” &lt;/#list&gt;

    Java面试枚举从使用到原理

    本篇文章将深入探讨Java枚举的使用及其背后的原理。 一、枚举的定义与使用 1. 基本用法: 在Java中,枚举可以通过`enum`关键字来创建。例如,我们可以定义一个表示一周七天的枚举类型: ```java public enum ...

    Java枚举类型Enum的用法

    Java枚举类型(Enum)是Java SE 5.0引入的一种新的数据类型,它为开发者提供了更为强大且安全的方式来表示一组常量。枚举在Java中不仅是一个类,还是一种特殊的类型,允许我们定义自己的常量集合。接下来,我们将...

    简单总结java枚举类型

    枚举在Java中被引入为一个完整的类型,不同于C++中的枚举,这使得Java枚举更加强大且易于使用。以下是关于Java枚举类型的详细解释和相关知识点: 1. 定义枚举: 在Java中,枚举通过关键字`enum`来定义。例如,创建...

    java枚举ppt和详细代码

    Java枚举是面向对象编程中的一个重要特性,它用于定义固定的常量集合,这些常量通常代表某种特定的数据类型。在Java中,枚举提供了一种更安全、更规范的方式来处理常量,相比于传统的final static变量,枚举具有更多...

    java枚举类型说明

    下面是一些关于Java枚举的基础知识点: - **定义**: 使用`enum`关键字定义枚举类型,可以在枚举类型中定义一组固定的值,这些值都是该枚举类型的实例。 - **实例**: 枚举类型的每一个值都可以看作是该枚举类型的一...

    JAVA高级编程中Enum枚举

    本资源包提供了一些关于`Enum`枚举的深入学习材料,包括实例、常见问题以及相关的文档,非常适合Java开发者进行高级编程的学习和复习。 首先,枚举的基本语法是定义一个公共类,前面加上关键字`enum`。例如: ```...

    java中enum枚举的详细用法

    Java中的枚举(enum)类型是在JDK 1.5版本引入的一个强大的特性,它用于定义一组相关的常量。在C/C++等语言中,枚举通常用来表示一组具有固定值的常量集合,但在Java中,枚举不仅限于此,它提供了更多的功能和灵活性...

    在Java中使用枚举

    虽然Java在早期版本中没有直接支持枚举,但随着Java 5的发布,枚举类型被引入,以解决之前版本中的一些问题。以下是Java中枚举类型的一些关键特性和使用方式: 1. **类型安全**: - Java枚举确保了类型安全,因为...

    Java中的“枚举类型

    ### Java中的“枚举类型”知识点详解 #### 一、引言 在Java编程语言中,枚举(Enum)作为一种特殊的类,其设计初衷是为了更好地处理一组固定不变的常量集合。相较于传统的使用`static final`字段来表示常量的做法...

    java枚举状态机

    Java枚举(Enum)状态机是一种使用枚举类型来实现状态转换逻辑的编程技术,它在Java编程中被广泛应用于管理对象的状态变化。状态机是一种模型,用于描述一个系统或对象在不同时间点可能存在的状态以及如何从一个状态...

    全面掌握java枚举类型(enum-type)1

    在 Java 语言中,没有引入枚举类型之前,表示枚举类型的常用模式是声明一组具有 int 常量。这种方式称作 int 枚举模式。例如,定义一个 Season 类,使用 public static final int 来定义四季: ```java public ...

    JAVA的枚举实例以及应用

    JAVA的枚举实例以及应用

    java枚举类用法

    通过上述介绍,我们了解到Java枚举类的多种用法,包括声明、初始化、方法定义、构造器、转换为集合、遍历、比较、在switch语句中的应用以及序列化等。枚举类不仅提高了代码的可读性和安全性,还简化了常量管理,使得...

    理解java枚举类型

    Java枚举类型是Java语言中的一种特殊的类,用于定义一组固定的常量集合。它在Java中扮演着重要的角色,提供了一种安全、类型化的常量表示方式,比传统的final static变量更具有优势。理解Java枚举类型对于编写高质量...

Global site tag (gtag.js) - Google Analytics