Java中“enum”的用途是什么?

时间:2012-03-24 09:18:56

标签: java enums

所以我调查了这个“enum”类型,它对我来说似乎是一个美化的数组 / ArrayList / List。它的用途究竟是什么?

8 个答案:

答案 0 :(得分:72)

如果该类应具有固定的枚举可用实例数,则使用enum而不是class

<强>示例:

  • DayOfWeek = 7个实例→enum
  • CardSuit = 4个实例→enum
  • Singleton = 1个实例→enum

  • Product =可变数量的实例→class
  • User =可变数量的实例→class
  • Date =可变数量的实例→class

答案 1 :(得分:70)

Enum作为一种固定数量的常量,至少可以用于两件事

<强>常数

public enum Month {
    JANUARY, FEBRUARY, ...
}

这比创建一堆整数常量要好得多。

创建单身

public enum Singleton {
    INSTANCE

   // init
};

你可以用枚举做很有趣的事情,看看here

另请查看official documentation

答案 2 :(得分:45)

枚举类型基本上是一种数据类型,它允许您以更可读和可靠的方式描述类型的每个成员。

这是一个简单的例子来解释原因:

假设你正在编写一个与季节有关的方法:

int枚举模式

首先,您声明了一些int静态常量来表示每个季节。

public static final int SPRING = 0;
public static final int SUMMER = 1;
public static final int FALL = 2;
public static final int WINTER = 2;

然后,您宣布了一种方法,将季节名称打印到控制台中。

public void printSeason(int seasonCode) {
    String name = "";
    if (seasonCode == SPRING) {
        name = "Spring";
    }
    else if (seasonCode == SUMMER) {
        name = "Summer";
    }
    else if (seasonCode == FALL) {
        name = "Fall";
    }
    else if (seasonCode == WINTER) {
        name = "Winter";
    }
    System.out.println("It is " + name + " now!");
}

那么,之后,您可以打印这样的季节名称。

printSeason(SPRING);
printSeason(WINTER);

这是为类中不同类型的成员执行不同操作的一种非常常见(但不好)的方法。但是,由于这些代码涉及整数,因此您也可以毫无问题地调用此方法。

printSeason(0);
printSeason(1);

甚至喜欢这个

printSeason(x - y);
printSeason(10000);

编译器不会抱怨,因为这些方法调用是有效的,并且您的printSeason方法仍然有效。

但有些事情不对。 10000的季节代码应该是什么意思?如果x - y导致负数会怎样?当你的方法收到一个没有意义且不应该在那里的输入时,你的程序对此一无所知。

您可以修复此问题,例如,添加其他支票。

...
else if (seasonCode == WINTER) {
    name = "Winter";
}
else {
    throw new IllegalArgumentException();
}
System.out.println(name);

现在,当季节代码无效时,程序将抛出RunTimeException。但是,您仍需要决定如何处理异常。

顺便说一下,我确定您注意到FALLWINTER的代码都是2,对吗?

你现在应该明白这个想法。这种模式很脆弱。它让你在任何地方写条件检查。如果你正在制作一款游戏,并且你想在你想象的世界中增加一个额外的季节,这种模式将让你通过所有按季节做事的方法,在大多数情况下你会忘记其中一些。

您可能认为类继承对于这种情况是个好主意。但我们只需要其中一些而不再需要。

那是enum发挥作用的时候。


使用enum类型

在Java中,enum类型是通过公共静态最终字段为每个枚举常量导出一个实例的类。

在这里,您可以声明四个枚举常量:SPRING, SUMMER, FALL, WINTER。每个都有自己的name

public enum Season {
    SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter");

    private String name;

    Season(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

现在,回到方法。

public void printSeason(Season season) {
    System.out.println("It is " + season.getName() + " now!");
}

现在可以使用int作为输入,而不是使用Season。您可以告诉Season为您提供名称,而不是条件检查。

现在使用此方法:

printSeason(Season.SPRING);
printSeason(Season.WINTER);
printSeason(Season.WHATEVER); <-- compile error

当您使用不正确的输入时,您将收到编译时错误,并且只要程序编译,您就可以保证获得Season的非空单例引用。

当我们需要额外的季节时,我们只需在Season中添加另一个常量,而不再添加。

public enum Season {
    SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter"), 
    MYSEASON("My Season");

...

每当你需要一组固定的常量时,enum都是一个不错的选择(但并非总是如此)。它是一个更具可读性,更可靠和更强大的解决方案。

答案 3 :(得分:27)

枚举类型是一种类型,其字段由一组固定的常量组成。常见示例包括罗盘方向(NORTH,SOUTH,EAST和WEST的值)和星期几。

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

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

以下是一些代码,向您展示如何使用上面定义的Day枚举:

public class EnumTest {
    Day day;

    public EnumTest(Day day) {
        this.day = day;
    }

    public void tellItLikeItIs() {
        switch (day) {
            case MONDAY:
                System.out.println("Mondays are bad.");
                break;

            case FRIDAY:
                System.out.println("Fridays are better.");
                break;

            case SATURDAY: case SUNDAY:
                System.out.println("Weekends are best.");
                break;

            default:
                System.out.println("Midweek days are so-so.");
                break;
        }
    }

    public static void main(String[] args) {
        EnumTest firstDay = new EnumTest(Day.MONDAY);
        firstDay.tellItLikeItIs();
        EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
        thirdDay.tellItLikeItIs();
        EnumTest fifthDay = new EnumTest(Day.FRIDAY);
        fifthDay.tellItLikeItIs();
        EnumTest sixthDay = new EnumTest(Day.SATURDAY);
        sixthDay.tellItLikeItIs();
        EnumTest seventhDay = new EnumTest(Day.SUNDAY);
        seventhDay.tellItLikeItIs();
    }
}

输出结果为:

  星期一很糟糕。
周中的日子一般。星期五   更好。周末最好。周末最好。

Java编程语言枚举类型比其他语言中的对应类型强大得多。枚举声明定义了一个类(称为枚举类型)。枚举类主体可以包括方法和其他字段。编译器在创建枚举时会自动添加一些特殊方法。例如,它们有一个静态值方法,该方法返回一个数组,该数组按照声明的顺序包含枚举的所有值。此方法通常与for-each构造结合使用,以迭代枚举类型的值。例如,下面Planet类示例中的代码遍历太阳系中的所有行星。

for (Planet p : Planet.values()) {
    System.out.printf("Your weight on %s is %f%n",
                      p, p.surfaceWeight(mass));
}

除了属性和构造函数之外,Planet还有一些方法可以让您检索每个行星上物体的表面重力和重量。这是一个示例程序,它可以减轻你在地球上的重量(在任何单位)并在所有行星上计算和打印你的重量(在同一个单位):

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    private double mass() { return mass; }
    private double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }
}

如果从参数为175的命令行运行Planet.class,则会得到以下输出:

  

$ java Planet 175
您对MERCURY的体重是66.107583   VENUS的重量是158.374842
你在EARTH的重量是   175.000000
你在MARS的体重是66.279007
你在JUPITER的体重是442.847567
你的体重在SATURN是186.552719
你的   URANUS的体重是158.397260。你对NEPTUNE的体重是   199.207413

来源:http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

答案 4 :(得分:2)

Enum是一种安全类型,因此您无法在运行时分配新值。此外,您可以在switch语句中使用它(如int)。

答案 5 :(得分:0)

枚举是recommended way,为定义的一组内容提供易于记忆的名称(也可选择一些有限的行为)。

您应该使用枚举,否则您将使用多个静态整数常量(例如public static int ROLE_ADMIN = 0BLOOD_TYPE_AB = 2

使用枚举而不是这些的主要优点是类型安全,尝试使用错误值时的编译类型警告/错误以及为相关“常量”提供命名空间。此外,它们更易于在IDE中使用,因为它也有助于代码完成。

答案 6 :(得分:0)

Java编程语言enums远比其他语言中的对应语言强大得多,这些语言只不过是美化整数。新的枚举声明定义了一个完整的类(称为枚举类型)。除了解决在java 5.0之前使用的以下int Enum模式存在的所有问题(Not typesafe, No namespace, Brittleness and Printed values are uninformative):

public static final int SEASON_WINTER = 0;

它还允许您将任意方法和字段添加到枚举类型,实现任意接口等。枚举类型提供所有Object方法的高质量实现。它们是ComparableSerializable,串行表单旨在承受枚举类型中的任意更改。您也可以在switch案例中使用Enum。

阅读有关Java Enums http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html的完整文章,了解更多详情。

答案 7 :(得分:-7)

1)enum是面向对象方法中的关键字。

2)它用于在单行中编写代码,这不仅仅是那个。

     public class NAME
     {
        public static final String THUNNE = "";
        public static final String SHAATA = ""; 
        public static final String THULLU = ""; 
     }

-------This can be replaced by--------

  enum NAME{THUNNE, SHAATA, THULLU}

3)大多数开发人员不使用enum关键字,它只是一种替代方法..