Java 5中引入的Enum类的用途是什么?

Java 5中引入的Enum类的用途是什么?,java,enums,Java,Enums,我的建议是: 1) 要么enums只在编译之前存在(就像泛型一样;但我从来没有听说过任何关于它的事情,尽管到处都写着编译后泛型被删除) 2) 或者Enum是以某种方式保持向后兼容性的一种方法(但我还不这么认为) 还有其他建议吗?(顺便说一句,您是否在代码中使用过它?) UPD: 换句话说,有一个enum关键字和enum类。它们都出现在Java5中。问题是:为什么我们两者都需要 第二个问题:为什么Enum成为API的一部分?枚举的存在是为了表示类型安全的枚举(比使用int常量进行相同操作要好得多)

我的建议是:

1) 要么
enum
s只在编译之前存在(就像泛型一样;但我从来没有听说过任何关于它的事情,尽管到处都写着编译后泛型被删除)

2) 或者Enum是以某种方式保持向后兼容性的一种方法(但我还不这么认为)

还有其他建议吗?(顺便说一句,您是否在代码中使用过它?)

UPD:

换句话说,有一个
enum
关键字和
enum
类。它们都出现在Java5中。问题是:为什么我们两者都需要


第二个问题:为什么
Enum
成为API的一部分?

枚举的存在是为了表示类型安全的枚举(比使用
int
常量进行相同操作要好得多)

如果您询问
Enum
类本身的用途是什么-它将充当用户定义的
Enum
s的超类。每个枚举被编译成一个类,该类使用适当的泛型参数(即自身)扩展
enum

为什么这是通过语法糖而不是简单的子类来实现的?首先,它强制执行枚举具有的特定语法(构成枚举成员的静态实例)。另一个原因可能是,子类
Enum
所需的泛型操作对于以前从未见过任何泛型的开发人员来说非常混乱。通过将这种复杂性隐藏在一个新的关键字后面,开发人员不必自己破译它。最后,关键字意味着它是一个特殊的构造,不应该像普通类一样对待它。

From:

需要表示一组固定常量时,应随时使用枚举类型。这包括自然枚举类型,例如太阳系中的行星,以及在编译时知道所有可能值的数据集,例如菜单上的选项、命令行标志等等

枚举非常有用,是的,我在代码中已经多次使用它们


编辑:

…有一个枚举关键字和枚举类。它们都出现在Java5中。问题是:为什么我们两者都需要

这个问题类似于问“有一个
关键字和一个
对象
类。为什么我们需要这两个?”

在这两种情况下,关键字基本上都是对编译器的提示;您可以将它们视为语法糖,它可以节省您的击键次数,并让编译器做更少的工作(通过不让编译器猜测您所声明的内容)

我也看到了

…您在代码中使用过它吗

答案仍然是“是”。特别是,
Enum#valueOf()
是一种用于解析字符串的静态方法:

DayOfWeek d = Enum.valueOf(DayOfWeek.class, "TUESDAY");
但这当然也行得通:

DayOfWeek d = DayOfWeek.valueOf("TUESDAY");

添加了Enum,因此Enum提供的功能是可见的,并有文档记录。隐藏这个类会有什么好处

编译后不会删除泛型

不确定为什么需要枚举类来实现向后兼容性

我使用该类来读取枚举的作用,并在代码中检查枚举类型、valueOf等


讽刺的是,这个问题就在你的问题之前。它显示了使用该类的示例

这里有一些答案


在他们的

中查看推理的完整列表,我不确定2。但是我在Java中一直使用枚举。而不是做

public static final int OPTION_ONE = 1;
public static final int OPTION_TWO = 2;
你能行

public enum Option{one, two}
这更简洁,因为现在您可以像这样声明所有函数:

public void doSomething(Option o);
其中,按照旧方法,您必须执行
public void doSomething(inti)
,我可以传递任何整数。因此,从未检查该参数以确保其为有效选项。这使得编译时和运行时的代码更加清晰

我还经常使用Enum来处理相同事物的变体。假设我们有一个sort属性

你可以这样做,这是非常干净的,比案例陈述要好得多

public enum Sort {
        Everyone {
            @Override
            List<Checkin> refreshList(Client client, Location location) throws IOException {
                return client.checkins().getList();
            }
        },
        NearBy {
            @Override
            List<Checkin> refreshList(Client client, Location location) throws IOException {
                return client.checkinsNear(location.getLatitude(), location.getLongitude()).getList();
            }
        }; // and any other sorts

        abstract List<Checkin> refreshList(Client client, Location location) throws IOException;
    }
公共枚举排序{
每个人{
@凌驾
列表刷新列表(客户端、位置)引发IOException{
返回client.checkins().getList();
}
},
附近{
@凌驾
列表刷新列表(客户端、位置)引发IOException{
返回client.checkinsNear(location.getLatitude(),location.getLongitude()).getList();
}
};//还有其他种类的
抽象列表刷新列表(客户端、位置)抛出IOException;
}
两个枚举中的任何一个仅在 汇编


如果您在声明中谈论的是
enum
语法,而不是
class
语法,那么这是正确的。在字节码级别,Java枚举是与任何其他类一样的类。枚举语义基本上是由Java编译器实现的。

在我看来,枚举的主要优点是类型安全

假设您有一个函数,它可以通过具有固定可能性集的某个选项调用。说“销售”或“退货”。一个非常糟糕的解决方案是传入一个字符串,如:

public void doTransaction(String type)
{
  if (type.equals("sale"))
    ... do whatever ...
}
这种方法的一个大问题是,如果有人试着用“销售”或“航行”来称呼它。除非程序验证只传入有效的参数,否则拼写错误可能会产生神秘的错误

好吧,许多程序员为此创建了常量:

public final static int SALE=1, RETURN=2;
public void doTransaction(int type)
{
  if (type==SALE)
  ... do whatever ...
}
这好多了,但还是有问题。假设我们有两个参数:

public final static int SALE=1, RETURN=2;
public final static int DOMESTIC=1, FOREIGN=2;
public void doTransaction(int type, int locale)
{
  if (type==SALE && locale==DOMESTIC)
  ... etc ...
}
现在有人弄糊涂了,打电话给
doTransaction(国外,销售)
。这将成功编译,通过程序内的任何有效性测试,并给出完全错误的结果。因为如果你没有抓住它,参数的顺序就错了

枚举解决了这个问题。如果你改写

enum SaleType {SALE, RETURN};
enum Locale {DOMESTIC, FOREIGN};
public void doTransaction(SaleType type, Locale locale)
... etc ...
现在如果有人试图写,
doTransaction(Loc