继上篇文章:Java和C++(www.cppentry.com)在细节上的差异:程序设计结构
四、枚举:
枚举的是在Java 1.5SE 中开始支持的,以下为Java枚举的基本概念和应用技巧:
1. 所有的enum对象均是由class对象作为底层支持的,该对象继承自JDK中的Enum<E>,但是该底层类确实final类,既不能再被其他的类继承。
2. 枚举的出现完全替代了原有的"public static final"常量表示法,枚举以一种更加合理、优雅和安全的方式替换了原有的方案。其最基本的声明方式如下:
- public enum Color {
- RED, BLUE, BLACK, YELLOW
- }
3. Enum<E>中构造函数的原型为protected Enum(String name, int ordinal),自定义的枚举对象会将自身的名字以字符串的形式,同时将自己在整个常量从声明的顺序作为超类构造函数的两个参数传给超类并由超类完成必要的初始化,如:RED枚举常量将调用super("RED",0)。
4. 枚举中可以定义构造函数、域方法和域字段,但是枚举中的构造器必须是私有(private)的,如果自定义枚举中有了自定义的构造函数,那么每个枚举常量在声明时必须按照自定义构造函数的规则传入参数。枚举对象的构造函数只是在枚举常量对象声明的时刻才调用一次,之后再也不能像普通对象那样通过new的方法创建,见如下代码:
- public enum Size {
- SMALL(0.8),
- MEDIUM(1.0),
- LARGE(1.2);
- double pricingFactor;
- private Size(double p) {
- pricingFactor = p;
- }
- }
注:枚举常量列表必须写在最前面声明,否则编译器报错。
5. 可以给自定义枚举添加域方法,见如下代码:
- public enum Size {
- SMALL(0.8),
- MEDIUM(1.0),
- LARGE(1.2);
- private double pricingFactor;
- Size(double p) {
- pricingFactor = p;
- }
- public double getPricingFactor() {
- return pricingFactor;
- }
- }
6. 枚举中常用域方法:
- public enum Size{
- SMALL,
- MEDIUM,
- LARGE;
- }
- public static void main(String[] args){
-
- Size s1 = Size.SMALL;
-
- Size s2 = Enum.valueOf(Size.class, "SMALL");
-
- Size s3 = Size.valueOf("MEDIUM");
-
-
- System.out.println("Size.MEDIUM.equals(Enum.valueOf(Size.class, \"MEDIUM\")):"+
- Size.MEDIUM.equals(Enum.valueOf(Size.class, "MEDIUM")));
-
-
-
- for(Size s:Size.values()){
-
-
- System.out.println(s.ordinal()+" "+s.name()+" "+s.toString());
- }
-
- if (s1.compareTo(s3) < 0)
- System.out.println("Size.SMALL is less than Size.MEDIUM");
- }
7. 在枚举中可以声明基于特定常量的类主体,见如下代码:
- public enum Size {
-
-
- Small {
- @Override
- public double getPricingFactor() {
- return 0.8;
- }
- },
-
- Medium,
- Large,
- ExtraLarge {
- @Override
- public double getPricingFactor() {
- return 1.2;
- }
- },
- ExtraExtraLarge {
- @Override
- public double getPricingFactor() {
- return 1.2;
- }
- };
- public double getPricingFactor() {
- return 1.0;
- }
- }
- public static void main(String args[]) {
- for (Size s : Size.values()) {
- double d = s.getPricingFactor();
- System.out.println(s + " Size has pricing factor of " + d);
- }
- }
-
-
-
-
-
-
8. 枚举在switch语句中的用法,见如下代码:
- public enum Color {
- RED, BLUE, BLACK, YELLOW
- }
- public static void main(String[] args) {
- Color m = Color.BLUE;
-
- switch (m) {
- case RED:
- System.out.println("color is red");
- break;
- case BLACK:
- System.out.println("color is black");
- break;
- case YELLOW:
- System.out.println("color is yellow");
- break;
- case BLUE:
- System.out.println("color is blue");
- break;
- default:
- System.out.println("color is unknown");
- break;
- }
- }
9. 和枚举相关的两个容器EnumMap和EnumSet,声明和主要用法如下。
- EnumMap<K extends Enum<K>, V>
- EnumSet<E extends Enum<E>>
-
- public enum State {
- ON, OFF
- };
- public static void main(String[] args) {
-
- EnumSet stateSet = EnumSet.allOf(State.class);
- for (State s : stateSet)
- System.out.println(s);
-
-
- EnumMap stateMap = new EnumMap(State.class);
- stateMap.put(State.ON, "is On");
- stateMap.put(State.OFF, "is off");
- for (State s : State.values())
- System.out.println(s.name() + ":" + stateMap.get(s));
- }
-
-
- public enum Size {
- Small,Medium,Large
- }
- public static void main(String args[]) {
- Map<Size, Double> map = new EnumMap<Size, Double>(Size.class);
- map.put(Size.Small, 0.8);
- map.put(Size.Medium, 1.0);
- map.put(Size.Large, 1.2);
- for (Map.Entry<Size, Double> entry : map.entrySet())
- helper(entry);
- }
- private static void helper(Map.Entry<Size, Double> entry) {
- System.out.println("Map entry: " + entry);
- }
10. Java枚举和C++(www.cppentry.com)枚举的主要区别为两点,一是C++(www.cppentry.com)中的枚举中只能定义常量,主要用于switch子句,二是C++(www.cppentry.com)中的枚举常量可以直接和数值型变量进行各种数学运算。