Java枚举

时间:2020-01-09 10:35:43  来源:igfitidea点击:

Java枚举是一种特殊的Java类型,用于定义常量的集合。更准确地说,Java枚举类型是一种特殊的Java类。枚举可以包含常量,方法等。Java枚举是在Java 5中添加的。

该Java枚举教程说明了如何创建和使用Java枚举。如果我们喜欢视频,请在此处查看本教程的视频版本:

枚举示例

这是一个简单的Java枚举示例:

public enum Level {
    HIGH,
    MEDIUM,
    LOW
}

注意enum关键字,它被用来代替" class"或者" interface"。 Java关键字enum向Java编译器发出信号,该类型定义是一个枚举。

我们可以像这样在上面的枚举中引用常量:

Level level = Level.HIGH;

注意" level"变量的类型是" Level"的类型," Level"是上面示例中定义的Java枚举类型。 " level"变量可以将" Level"枚举常量之一作为值(" HIGH"," MEDIUM"或者" LOW")。在这种情况下," level"设置为" HIGH"。

if语句中的枚举

由于Java枚举是常量,因此我们通常必须将指向枚举常量的变量与枚举类型中可能的常量进行比较。这是在if语句中使用Java枚举的示例:

Level level = ...  //assign some Level constant to it

if( level == Level.HIGH) {

} else if( level == Level.MEDIUM) {

} else if( level == Level.LOW) {

}

该代码将" level"变量与" Level"枚举中的每个可能的枚举常量进行比较。

如果其中一个枚举值比其他枚举值出现的频率更高,则在第一个" if"语句中检查该值将导致更好的性能,因为平均执行的比较较少。除非比较执行得很多,否则这并不是很大的区别。

开关语句中的枚举

如果Java枚举类型包含很多常量,并且我们需要按照上一节中显示的值检查变量,那么使用Javaswitch语句可能是一个好主意。

我们可以在switch语句中使用枚举,如下所示:

Level level = ...  //assign some Level constant to it

switch (level) {
    case HIGH   : ...; break;
    case MEDIUM : ...; break;
    case LOW    : ...; break;
}

如果level变量与给定的Level常量值匹配,则将代码替换为......以执行。该代码可以是简单的Java操作,方法调用等。

枚举迭代

我们可以通过调用Java枚举类型的静态values()方法来获取其所有可能值的数组。 Java编译器会自动为所有枚举类型获取一个静态的values()方法。这是一个迭代枚举的所有值的示例:

for (Level level : Level.values()) {
    System.out.println(level);
}

运行此Java代码将打印出所有枚举值。这是输出:

HIGH
MEDIUM
LOW

注意常量本身的名称是如何打印出来的。这是Java枚举不同于"静态最终"常量的领域。

枚举toString()

枚举类在编译时会自动在该类中获取一个" toString()"方法。 toString()方法返回给定枚举实例名称的字符串值。这是一个例子:

String levelText = Level.HIGH.toString();

执行以上语句后,levelText变量的值将为文本HIGH

枚举打印

如果我们打印枚举,如下所示:

System.out.println(Level.HIGH);

然后,将在后台调用toString()方法,因此将要输出的值是枚举实例的文本名称。换句话说,在上面的示例中,文本" HIGH"将被打印出来。

枚举valueOf()

枚举类在编译时会自动在该类中获取静态的valueOf()方法。 valueOf()方法可用于获取给定String值的enum类的实例。这是一个例子:

Level level = Level.valueOf("HIGH");

执行此行后,level变量将指向Level.HIGH

枚举字段

我们可以将字段添加到Java枚举。因此,每个常量枚举值都将获取这些字段。定义常量时,必须将字段值提供给枚举的构造函数。这是一个例子:

public enum Level {
    HIGH  (3),  //calls constructor with value 3
    MEDIUM(2),  //calls constructor with value 2
    LOW   (1)   //calls constructor with value 1
    ; // semicolon needed when fields / methods follow

    private final int levelCode;

    private Level(int levelCode) {
        this.levelCode = levelCode;
    }
}

请注意,上面示例中的Java枚举如何具有采用int的构造函数。枚举构造函数设置" int"字段。定义常量枚举值时,会将一个" int"值传递给枚举构造函数。

enum构造函数必须是private或者包作用域(默认)。我们不能为Java枚举使用" public"或者" protected"构造函数。

枚举方法

我们也可以将方法添加到Java枚举。这是一个例子:

public enum Level {
    HIGH  (3),  //calls constructor with value 3
    MEDIUM(2),  //calls constructor with value 2
    LOW   (1)   //calls constructor with value 1
    ; // semicolon needed when fields / methods follow

    private final int levelCode;

    Level(int levelCode) {
        this.levelCode = levelCode;
    }
    
    public int getLevelCode() {
        return this.levelCode;
    }
    
}

我们可以通过引用常量值之一来调用Java枚举方法。这是Java枚举方法调用示例:

Level level = Level.HIGH;

System.out.println(level.getLevelCode());

该代码将输出值" 3",该值是枚举常量" HIGH"的" levelCode"字段的值。

我们不仅限于简单的getter和setter方法。我们还可以创建基于枚举常量的字段值进行计算的方法。如果字段未声明为" final",我们甚至可以修改字段的值(尽管考虑到枚举应为常量,但这并不是一个好主意)。

枚举抽象方法

Java枚举类也可能具有抽象方法。如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。这是一个Java枚举抽象方法示例:

public enum Level {
    HIGH{
        @Override
        public String asLowerCase() {
            return HIGH.toString().toLowerCase();
        }
    },
    MEDIUM{
        @Override
        public String asLowerCase() {
            return MEDIUM.toString().toLowerCase();
        }
    },
    LOW{
        @Override
        public String asLowerCase() {
            return LOW.toString().toLowerCase();
        }
    };

    public abstract String asLowerCase();
}

注意枚举类底部的抽象方法声明。还请注意,每个枚举实例(每个常量)如何定义此抽象方法自己的实现。当我们需要为Java枚举的每个实例使用不同的方法实现时,使用抽象方法很有用。

枚举实现接口

Java" Enum"可以实现Java接口,以防我们觉得自己的情况有意义。这是实现接口的JavaEnum的示例:

public enum EnumImplementingInterface implements MyInterface {
    FIRST("First Value"), SECOND("Second Value");

    private String description = null;

    private EnumImplementingInterface(String desc){
        this.description = desc;
    }

    @Override
    public String getDescription() {
        return this.description;
    }
}

方法" getDescription()"来自接口" MyInterface"。

用" Enum"实现接口可用于实现一组不同的" Comparator"常量,这些常量可用于对对象集合进行排序。 Java集合排序教程中更详细地说明了Java中对象的排序。

枚举集

Java包含一个称为EnumSet的特殊Java Set实现,它比标准Java Set实现更有效地保存枚举。这是创建EnumSet实例的方法:

EnumSet<Level> enumSet = EnumSet.of(Level.HIGH, Level.MEDIUM);

创建后,我们可以像使用其他Set一样使用EnumSet

枚举Map

Java还包含一个特殊的Java Map实现,可以将Java枚举实例用作键。这是一个JavaEnumMap示例:

EnumMap<Level, String> enumMap = new EnumMap<Level, String>(Level.class);
enumMap.put(Level.HIGH  , "High level");
enumMap.put(Level.MEDIUM, "Medium level");
enumMap.put(Level.LOW   , "Low level");

String levelValue = enumMap.get(Level.HIGH);

枚举其他详细信息

Java枚举隐式扩展了java.lang.Enum类,因此枚举类型无法扩展另一个类。

如果Java枚举包含字段和方法,则字段和方法的定义必须始终在枚举中的常量列表之后。此外,枚举常量列表必须以分号结尾。