让你的系统更安全--用枚举enum替代int常量

发布于 2019-08-25 | 作者: 职场咖啡 | 来源: 网易号 | 转载于: 网易号

做应用系统时,我们往往假设用户是小白,那么为了保证系统的正常,我们往往会对用户的参数做限制,并且前后端都要对用户的参数做验证。那我们在设计的时候是否可以提前预防这种问题呢?其中的一种方式就是:用枚举enum替代int常量。

枚举的好处:

1. 类型安全性

2.使用方便性

示例1

public class EnumDemo {
    enum Color{
        RED(3),BLUE(5),BLACK(8),YELLOW(13),GREEN(28);
        
        private int colorValue;
        
        private Color(int rv){
            this.colorValue=rv;
        }
        
        private int getColorValue(){
            return colorValue;
        }
        
        private int value(){
            return ordinal()+1;
        }
    }
    
    public static void main(String[] args) {
        for(Color s : Color.values()) {
            //enum的values()返回一个数组,这里就是Seasons[]
            System.out.println(s.value()+":"+s.name()+"="+s.getColorValue());
        }
    }
}

output:

1:RED=3
2:BLUE=5
3:BLACK=8
4:YELLOW=13
5:GREEN=28

其中,

/**
 * Returns the ordinal of this enumeration constant (its position in its enum declaration, where the initial
 * constant is assigned an ordinal of zero).
 *
 * Most programmers will have no use for this method. It is designed for use by sophisticated enum-based data
 * structures, such as {@link java.util.EnumSet} and {@link java.util.EnumMap}.
 *
 * @return the ordinal of this enumeration constant
 */
 public final int ordinal() {
    return ordinal;
 }

示例2:

EnumMap是专门为枚举类型量身定做的Map实现。虽然使用其它的Map实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用EnumMap会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以EnumMap使用数组来存放与枚举类型对应的值。这使得EnumMap的效率非常高。

import java.util.*;
public enum Phase {
    SOLID, LIQUID, GAS;
    
    public enum Transition {
        MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID), BOIL(LIQUID, GAS), 
        CONDENSE(GAS, LIQUID), SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID);
        
        private final Phase src;
        private final Phase dst;
        
        Transition(Phase src, Phase dst) {
            this.src = src;
            this.dst = dst;
        }
        
        private static final Map<Phase, Map<Phase, Transition>> m = new EnumMap<Phase, Map<Phase, Transition>>(Phase.class);
        
        static {
            for (Phase p : Phase.values())
                m.put(p, new EnumMap<Phase, Transition>(Phase.class));
            
            for (Transition trans : Transition.values())
                m.get(trans.src).put(trans.dst, trans);
        }
        
        public static Transition from(Phase src, Phase dst) {
            return m.get(src).get(dst);
        }
    }
    
    public static void main(String[] args) {
        for (Phase src : Phase.values())
            for (Phase dst : Phase.values())
                if (src != dst)
                    System.out.printf("%s to %s : %s %n", src, dst,
                Transition.from(src, dst));
    }
}