杰瑞科技汇

Java中枚举(enumeration)怎么用?

Of course! Here is a comprehensive guide to Java enum (enumeration), covering everything from the basics to advanced features.

Java中枚举(enumeration)怎么用?-图1
(图片来源网络,侵删)

What is an enum in Java?

An enum (short for enumeration) is a special data type in Java that represents a fixed set of constants. It's a special kind of class that makes your code more readable, maintainable, and type-safe.

Think of it like a predefined list of options. For example, instead of using a String like "MONDAY", "TUESDAY", etc., you can use an enum that guarantees only valid values can be used.

Why Use Enums?

  1. Type Safety: The compiler prevents you from assigning an invalid value. You can't accidentally assign a String like "Funday" to a variable meant to hold a day of the week.
  2. Readability: DayOfWeek.MONDAY is much clearer than "MONDAY" or 0.
  3. Compile-Time Checking: Errors are caught at compile time, not at runtime.
  4. Can Have Fields, Methods, and Constructors: Enums are full-fledged classes, not just simple constants.

Basic Syntax and Usage

Here's how you define and use a simple enum.

Defining an Enum

// File: DayOfWeek.java
public enum DayOfWeek {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}

Notice the syntax: public enum EnumName { CONSTANT1, CONSTANT2, ... }. By convention, enum constants are written in UPPER_CASE.

Java中枚举(enumeration)怎么用?-图2
(图片来源网络,侵删)

Using an Enum

You can declare a variable of the enum type and assign it one of its constants.

public class Main {
    public static void main(String[] args) {
        // Declare a variable of type DayOfWeek
        DayOfWeek today;
        // Assign a value to it
        today = DayOfWeek.FRIDAY;
        // Use it in a switch statement
        switch (today) {
            case MONDAY:
                System.out.println("The weekend is far away.");
                break;
            case FRIDAY:
                System.out.println("TGIF! The weekend is almost here!");
                break;
            case SATURDAY:
            case SUNDAY:
                System.out.println("It's the weekend!");
                break;
            default:
                System.out.println("It's a weekday.");
        }
    }
}

Output:

TGIF! The weekend is almost here!

Advanced Features of Enums

Since an enum is a class, you can add much more functionality to it.

Adding Fields and Constructors

Let's create an enum for planets that includes their mass and radius.

public enum Planet {
    // Each constant is an instance of the Planet enum
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6);
    // Fields
    private final double mass;   // in kilograms
    private final double radius; // in meters
    // Constructor (must be private or package-private)
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    // Public methods
    public double getMass() {
        return mass;
    }
    public double getRadius() {
        return radius;
    }
    public double surfaceGravity() {
        // G is the gravitational constant
        return G * mass / (radius * radius);
    }
    private static final double G = 6.67300E-11; // Gravitational constant
}
public class Main {
    public static void main(String[] args) {
        Planet earth = Planet.EARTH;
        System.out.println("Earth's mass: " + earth.getMass());
        System.out.printf("Earth's surface gravity: %.2f m/s^2\n", earth.surfaceGravity());
    }
}

Output:

Earth's mass: 5.976E24
Earth's surface gravity: 9.80 m/s^2

Key Points:

  • The constructor is private by default. You cannot create new Planet() from outside the enum.
  • Each constant (MERCURY, VENUS, etc.) implicitly calls the constructor with the provided arguments.

Adding Methods

You can add any method you would add to a normal class. A very common pattern is to add a toString() method or a method that returns a custom string representation.

public enum TrafficLight {
    RED("Stop"),
    YELLOW("Caution"),
    GREEN("Go");
    private final String description;
    TrafficLight(String description) {
        this.description = description;
    }
    @Override
    public String toString() {
        return description;
    }
}
public class Main {
    public static void main(String[] args) {
        System.out.println("The light is: " + TrafficLight.RED);
        System.out.println("The light is: " + TrafficLight.GREEN);
    }
}

Output:

The light is: Stop
The light is: Go

Implementing Interfaces

An enum can implement an interface, just like a regular class.

// An interface
interface Printable {
    void print();
}
// An enum implementing the interface
public enum Status implements Printable {
    RUNNING, STOPPED, PENDING;
    @Override
    public void print() {
        System.out.println("Current status: " + this);
    }
}
public class Main {
    public static void main(String[] args) {
        Status.RUNNING.print(); // Calls the implemented method
    }
}

Output:

Current status: RUNNING

The values() and valueOf() Methods

The compiler automatically provides two static utility methods for every enum.

  • values(): Returns an array containing all the constants of the enum in the order they are declared.

    for (DayOfWeek day : DayOfWeek.values()) {
        System.out.println(day);
    }
    // Output:
    // MONDAY
    // TUESDAY
    // ...
    // SUNDAY
  • valueOf(String name): Returns the enum constant with the specified name. It's case-sensitive and throws an IllegalArgumentException if the name doesn't match any constant.

    Day monday = DayOfWeek.valueOf("MONDAY"); // OK
    System.out.println(monday);
    // Day fakeDay = DayOfWeek.valueOf("MONDAYY"); // Throws IllegalArgumentException

Using EnumSet and EnumMap

Java provides specialized, high-performance Set and Map implementations for enums.

  • EnumSet: A highly efficient Set implementation for enum types. It's internally implemented as a bit vector, making it very fast and memory-efficient.

    // A set of weekdays
    Set<DayOfWeek> weekdays = EnumSet.range(DayOfWeek.MONDAY, DayOfWeek.FRIDAY);
    System.out.println(weekdays); // [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
  • EnumMap: A highly efficient Map implementation where the keys are of an enum type.

    // A map to associate a day with a task
    Map<DayOfWeek, String> schedule = new EnumMap<>(DayOfWeek.class);
    schedule.put(DayOfWeek.MONDAY, "Team meeting");
    schedule.put(DayOfWeek.FRIDAY, "Code review");
    System.out.println(schedule.get(DayOfWeek.MONDAY)); // Team meeting

Best Practices

  1. Use Enums for Constants: Whenever you have a fixed set of related constants (like days, planets, statuses, suits in a deck of cards), prefer an enum over static final integers or strings.
  2. Keep it Simple: For simple cases, just define the constants. Don't add unnecessary complexity.
  3. Use EnumSet and EnumMap: When you need a Set or Map of your enum types, always use these specialized collections for performance benefits.
  4. Avoid ordinal(): The ordinal() method returns the position of an enum constant (0, 1, 2...). Avoid using it in application code, as it's fragile. If you reorder the constants in the enum definition, any code relying on ordinal() will break silently. Use the constants themselves for comparisons.

Summary: enum vs. public static final

Feature public static final Constants enum
Type Safety Poor. A String or int can be assigned any value. Excellent. Compiler ensures only valid enum constants are used.
Readability int status = 1; is not self-documenting. Status status = Status.RUNNING; is clear.
Methods/Fields No. You need a separate class or utility methods. Yes. Enums are full-fledged classes.
Collections Use HashSet, HashMap, etc. Use specialized EnumSet, EnumMap for better performance.
Maintainability Harder. If you add a new constant, you must find all usages of the number 3 and check if it's related. Easier. The compiler helps you find all places where the enum is used.
分享:
扫描分享到社交APP
上一篇
下一篇