zoukankan      html  css  js  c++  java
  • 如何将整型数转换为枚举类型以方便在switch中的使用

    Java中enum跟int不一样,相当于两个不同的类型,不能相互转化,如果需要转换需要增加额外的方法。如果自己定义初值,并且希望可以根据数值在switch里面进行方便的比较,需要做一些特别的处理。
    Enum的原型如下:

    public abstract class Enum<E extends Enum<E>> implements Serializable, Comparable<E>  {
        private final String name;
        private final int ordinal;
    }


    其中,name就是你定义的枚举的名字,如EStudent、ETeacher等。ordinal按照你定义的先后顺序顺次排列,值为0、1、2...。


    需要注意的是,android里面Enum类型是不能被继承的,而且重写起来也非常困难,比如需要BasicLruCache.javaEmptyArray.javaClass.java等诸多文件,而Class.java又引用了很多的包,比如:

    import sun.misc.Unsafe;
    import sun.reflect.ConstantPool;
    import sun.reflect.Reflection;
    import sun.reflect.ReflectionFactory;
    import sun.reflect.SignatureIterator;
    import sun.reflect.generics.factory.CoreReflectionFactory;
    import sun.reflect.generics.factory.GenericsFactory;
    import sun.reflect.generics.repository.ClassRepository;
    import sun.reflect.generics.repository.MethodRepository;
    import sun.reflect.generics.repository.ConstructorRepository;
    import sun.reflect.generics.scope.ClassScope;
    import sun.security.util.SecurityConstants;
    import sun.reflect.annotation.*;
    ......


    因此,要重写一个MyEnum替代enum是比较困难的:
    public abstract class MyEnum<E extends MyEnum<E>> implements Serializable, Comparable<E>  {
    }


    但是要达到上述目的却是可以的,看下面的例子。
    这是用户的期望:

    int val = 2;
    MyEnum type = EnumUtils.getMyEnum(MyEnum.class, val);
    val = 10;
    MyEnum defaultType = MyEnum.EUnknown;
    type = EnumUtils.getMyEnum(MyEnum.class, val, defaultType);
    switch(type) {
    case EUnknown:
       break;
    case EStudent:
       break;
    case STeacher:
       break;
    }



    在实际项目中,MyEnum 的枚举值可能是这样的:

    public enum MyEnum {
        EUnknown(0),
        EStudent(2),
        STeacher(3);
    }


    甚至是这样的:

            ENewsText(0x1001),                  
            ENewsWithSlide(0x1002),        
            ENewsWithVideo(0x1003),         
            ENewsComment(0x1004),          
    
    
            EMatch(0x2000),                         //比赛,小于0x2000的是新闻
            
            EMatchLiveVideoPresent(0x2001),  
            EMatchLiveTextPresent(0x2002),  
            EMatchOver(0x2003),                
            EMatchLiveVideoDNS(0x2004),     
            EMatchLiveTextDNS(0x2005),      


    因此,首先需要实现赋初值(private):

        int val;
        MyEnum(int val) {
            this.val = val;
        }


    其次,要实现int与enum的转换。
    enum转换为int,非常简单,只需要注意到val与ordinal的不同:

        public int getVal() {
            return val; 
        }



    最后,要实现int转换为enum,强大的Java当然不会傻瓜到需要你通过switch(val)的方式返回不同的enum值,可以通过如下的方式:

        public static <T extends Enum<T>> T getMyEnum(Class<T> enumType, int val) {
            return getMyEnum(enumType, val, null);
        }
        
        public static <T extends Enum<T>> T getMyEnum(Class<T> enumType, int val, T defaultT) {        
            T ret = defaultT;
            try {
                T[] myEnums = enumType.getEnumConstants();
                Field fl = enumType.getDeclaredField("val");
                if(myEnums != null && myEnums.length > 0) {                
                    for(T t : myEnums) {
                        try {
                            if(val == fl.getInt(t)) {
                                ret = t;
                                break;
                            }
                        } catch (IllegalArgumentException e) {
    //                        e.printStackTrace();
                        } catch (IllegalAccessException e) {
    //                        e.printStackTrace();
                        }
                    }
                }
            } catch (NoSuchFieldException e) {
    //            e.printStackTrace();
            } catch(NullPointerException e) {
    //            e.printStackTrace();
            }
            return ret;
        }






    菜鸟们,勇敢地拿去吧! ^_^

  • 相关阅读:
    巴洛克式和哥特式的区别
    推荐阅读书籍,是时候再行动起来了。
    AtCoder ABC 159F Knapsack for All Segments
    AtCoder ABC 159E Dividing Chocolate
    AtCoder ABC 158F Removing Robots
    AtCoder ABC 158E Divisible Substring
    AtCoder ABC 157F Yakiniku Optimization Problem
    AtCoder ABC 157E Simple String Queries
    AtCoder ABC 157D Friend Suggestions
    AtCoder ABC 156F Modularness
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3109038.html
Copyright © 2011-2022 走看看