曲阜住房城乡建设局网站,网页公司制作,seo推广小分享,网页设计网站建设报告文章目录 第二十二章 枚举1. 基本功能1.1 基本 enum 特性 2. 方法添加2.1 方法添加2.2 覆盖 enum 的方法 3 switch 语句中的 enum4. values 方法的神秘之处5. 实现而非继承6. 随机选择7. 使用接口组织枚举8. 使用 EnumSet 替代 Flags9. 使用 EnumMap10. 常量特定方法11. 本章小… 文章目录 第二十二章 枚举1. 基本功能1.1 基本 enum 特性 2. 方法添加2.1 方法添加2.2 覆盖 enum 的方法 3 switch 语句中的 enum4. values 方法的神秘之处5. 实现而非继承6. 随机选择7. 使用接口组织枚举8. 使用 EnumSet 替代 Flags9. 使用 EnumMap10. 常量特定方法11. 本章小结 第二十二章 枚举 关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型而这些具名的值可以作为常规的程序组件使用。这是一种非常有用的功能 1. 基本功能
1.1 基本 enum 特性
package enums;enum Shrubbery {GROUND, CRAWLING, HANGING}public class EnumClass {public static void main(String[] args) {for (Shrubbery s : Shrubbery.values()) { // 实例 .values() 方法返回 enum 实例的数组System.out.println(s ordinal: s.ordinal()); // ordinal() 方法返回 enum 实例在声明时的次序从 0 开始System.out.print(s.compareTo(Shrubbery.CRAWLING) );System.out.print(s.equals(Shrubbery.CRAWLING) );System.out.println(s Shrubbery.CRAWLING);System.out.println(s.getDeclaringClass()); // 其所属的 enum 类System.out.println(s.name()); // 获取值System.out.println(********************);}for (String s :HANGING CRAWLING GROUND AA.split( )) {// valueOf() 是在 Enum 中定义的 static 方法// 它根据给定的名字返回相应的 enum 实例// 如果不存在给定名字的实例将会抛出异常Shrubbery shrub Enum.valueOf(Shrubbery.class, s);System.out.println(shrub);}}
}输出
GROUND ordinal: 0
-1 false false
class enums.Shrubbery
GROUND
********************
CRAWLING ordinal: 1
0 true true
class enums.Shrubbery
CRAWLING
********************
HANGING ordinal: 2
1 false false
class enums.Shrubbery
HANGING
********************
HANGING
CRAWLING
GROUND
Exception in thread main java.lang.IllegalArgumentException: No enum constant enums.Shrubbery.AAat java.lang.Enum.valueOf(Enum.java:238)at enums.EnumClass.main(EnumClass.java:32)2. 方法添加
2.1 方法添加
除了不能继承自一个 enum 之外基本上可以将 enum 看作一个常规的类。也就是说可以向 enum 中添加方法。enum 甚至可以有 main() 方法。
一般来说我们希望每个枚举实例能够返回对自身的描述而不仅仅只是默认的 toString() 实现这只能返回枚举实例的名字。为此你可以提供一个构造器专门负责处理这个额外的信息然后添加一个方法返回这个描述信息。
package enums;public enum OzWitch {WEST(Miss Gulch, aka the Wicked Witch of the West),NORTH(Glinda, the Good Witch of the North),EAST(Wicked Witch of the East, wearer of the Ruby Slippers, crushed by Dorothys house),SOUTH(Good by inference, but missing);private String description;OzWitch(String description) {this.description description;}public String getDescription() {return description;}public static void main(String[] args) {for (OzWitch witch : OzWitch.values()) {System.out.println(witch witch.getDescription());}}
}输出
WESTMiss Gulch, aka the Wicked Witch of the West
NORTHGlinda, the Good Witch of the North
EASTWicked Witch of the East, wearer of the Ruby Slippers, crushed by Dorothys house
SOUTHGood by inference, but missing2.2 覆盖 enum 的方法
package enums;import java.util.stream.Stream;public enum SpaceShip {SCOUT, CARGO, TRANSPORT,CRUISER, BATTLESHIP, MOTHERSHIP;Overridepublic String toString() {String id name();String lower id.substring(1).toLowerCase();return id.charAt(0) lower;}public static void main(String[] args) {Stream.of(values()).forEach(System.out::println);}
}输出
Scout
Cargo
Transport
Cruiser
Battleship
Mothership3 switch 语句中的 enum
在 switch 中使用 enum是 enum 提供的一项非常便利的功能。一般来说在 switch 中只能使用整数值而枚举实例天生就具备整数值的次序并且可以通过 ordinal() 方法取得其次序显然编译器帮我们做了类似的工作。
package enums;enum Signal {GREEN, YELLOW, RED,}public class TrafficLight {Signal color Signal.RED;public void change() {switch (color) {case RED:color Signal.GREEN;break;case GREEN:color Signal.YELLOW;break;case YELLOW:color Signal.RED;break;}}Overridepublic String toString() {return The traffic light is color;}public static void main(String[] args) {TrafficLight t new TrafficLight();for (int i 0; i 5; i) {System.out.println(t);t.change();}}
}输出
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
The traffic light is GREEN4. values 方法的神秘之处
前面已经提到编译器为你创建的 enum 类都继承自 Enum 类。然而如果你研究一下 Enum 类就会发现它并没有 values() 方法。答案是values() 是由编译器添加的 static 方法。
5. 实现而非继承
所有的 enum 都继承自 Java.lang.Enum 类。由于 Java 不支持多重继承所以你的 enum 不能再继承其他类
enum NotPossible extends Pet { ... // Wont work然而在我们创建一个新的 enum 时可以同时实现一个或多个接口。
6. 随机选择
package onjava;import java.util.Random;public class Enums {private static Random rand new Random(47);public static T extends EnumT T random(ClassT ec) {return random(ec.getEnumConstants());}public static T T random(T[] values) {return values[rand.nextInt(values.length)];}
}package enums;import onjava.Enums;enum Activity {SITTING, LYING, STANDING, HOPPING,RUNNING, DODGING, JUMPING, FALLING, FLYING
}public class RandomTest {public static void main(String[] args) {for (int i 0; i 20; i) {Activity random Enums.random(Activity.class);System.out.print(random );}}
}输出
STANDING FLYING RUNNING STANDING RUNNING STANDING LYING DODGING SITTING RUNNING HOPPING HOPPING HOPPING RUNNING STANDING LYING FALLING RUNNING FLYING LYING 7. 使用接口组织枚举
在一个接口的内部创建实现该接口的枚举以此将元素进行分组可以达到将枚举元素分类组织的目的。
package enums.menu;public interface Food {enum Appetizer implements Food {SALAD, SOUP, SPRING_ROLLS;}enum MainCourse implements Food {LASAGNE, BURRITO, PAD_THAI,LENTILS, HUMMOUS, VINDALOO;}enum Dessert implements Food {TIRAMISU, GELATO, BLACK_FOREST_CAKE,FRUIT, CREME_CARAMEL;}enum Coffee implements Food {BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,LATTE, CAPPUCCINO, TEA, HERB_TEA;}
}package enums.menu;
import static enums.menu.Food.*;public class TypeOfFood {public static void main(String[] args) {// 所有东西都是某种类型的 FoodFood food Appetizer.SALAD;food MainCourse.LASAGNE;food Dessert.GELATO;food Coffee.CAPPUCCINO;}
}8. 使用 EnumSet 替代 Flags
Java SE5 引入 EnumSet是为了通过 enum 创建一种替代品以替代传统的基于 int 的“位标志”。这种标志可以用来表示某种“开/关”信息。
EnumSet 中的元素必须来自一个 enum。
下面的 enum 表示在一座大楼中警报传感器的安放位置
package enums;public enum AlarmPoints {STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3,OFFICE4, BATHROOM, UTILITY, KITCHEN
}然后我们用 EnumSet 来跟踪报警器的状态
package enums;import java.util.EnumSet;import static enums.AlarmPoints.*;public class EnumSets {public static void main(String[] args) {// 创建一个空的 EnumSetEnumSetAlarmPoints points EnumSet.noneOf(AlarmPoints.class);// 添加元素points.add(BATHROOM);System.out.println(add: points);points.addAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));System.out.println(addAll: points);points EnumSet.allOf(AlarmPoints.class);System.out.println(EnumSet.allOf: points);points.removeAll(EnumSet.of(STAIR1, STAIR2, KITCHEN));System.out.println(removeAll: points);points.removeAll(EnumSet.range(OFFICE1, OFFICE4));System.out.println(removeAll-EnumSet.range: points);points points.complementOf(points);System.out.println(complementOf: points);}
}输出
add:[BATHROOM]
addAll:[STAIR1, STAIR2, BATHROOM, KITCHEN]
EnumSet.allOf:[STAIR1, STAIR2, LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, UTILITY, KITCHEN]
removeAll:[LOBBY, OFFICE1, OFFICE2, OFFICE3, OFFICE4, BATHROOM, UTILITY]
removeAll-EnumSet.range:[LOBBY, BATHROOM, UTILITY]
complementOf:[STAIR1, STAIR2, OFFICE1, OFFICE2, OFFICE3, OFFICE4, KITCHEN]9. 使用 EnumMap
EnumMap 是一种特殊的 Map它要求其中的键key必须来自一个 enum。
package enums;import java.util.*;import static enums.AlarmPoints.*;interface Command {void action();
}public class EnumMaps {public static void main(String[] args) {EnumMapAlarmPoints, Command em new EnumMap(AlarmPoints.class);em.put(KITCHEN,() - System.out.println(Kitchen fire!));em.put(BATHROOM,() - System.out.println(Bathroom alert!));for (Map.EntryAlarmPoints, Command e : em.entrySet()) {System.out.print(e.getKey() : );e.getValue().action();}try { // If theres no value for a particular key:em.get(UTILITY).action();} catch(Exception e) {System.out.println(Expected: e);}}
}10. 常量特定方法
Java 的 enum 有一个非常有趣的特性即它允许程序员为 enum 实例编写方法从而为每个 enum 实例赋予各自不同的行为。要实现常量相关的方法你需要为 enum 定义一个或多个 abstract 方法然后为每个 enum 实例实现该抽象方法。
package enums;public enum ConstantSpecificMethod {DATE_TIME {Overridevoid getInfo() {System.out.println(DATE_TIME);}},CLASSPATH {Overridevoid getInfo() {System.out.println(CLASSPATH);}};abstract void getInfo();public static void main(String[] args) {for (ConstantSpecificMethod v : values()) {v.getInfo();}}
}调用 getInfo() 方法时体现出多态的行为。
11. 本章小结
虽然枚举类型本身并不是特别复杂但还是将本章安排在全书比较靠后的位置这是因为程序员可以将 enum 与 Java 语言的其他功能结合使用例如多态、泛型和反射。 图网侵删