Java枚举类学习

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/cblstc/article/details/88820547

前言

枚举类对我而言一直是非常神秘的特性,最近学习thinking in Java,将枚举类的特性总结下,只为了加深印象。

枚举类

初探

枚举类的ordinal()表示序号,name()表示名称。
比较枚举类的大小可以放心使用==或equals to。
valueOf可以在枚举变量中寻找匹配的字符串并返回改变量。

enum Sports {
    BASKETBALL,
    SOCCOR,
    PINGPONG
}

public class EnumTest {

    public static void main(String[] args) {

        for (Sports sport : Sports.values()) {
            // 遍历enum集合
//            System.out.println(sport.ordinal());
//            System.out.println(sport.compareTo(Sports.BASKETBALL)); 
//            System.out.println(sport.equals(Sports.BASKETBALL));
//            System.out.println(sport == Sports.BASKETBALL);
//            System.out.println(sport.getDeclaringClass());
//            System.out.println(sport.name());
        }
        
        for (String s : "BASKETBALL SOCCOR PINGPONG".split(" ")) {
            Sports sport = Enum.valueOf(Sports.class, s);
            System.out.println(sport);
        }
    }
}

像类一样的枚举

枚举类型可以像类那样拥有成员变量,构造方法、成员方法

public enum EnumTest3 {

    BASKETBALL("Basketball is one of the most popular sports around the world."),
    SOCCOR("SOCCOR is not the same in England and America."),
    PINGPONG("PingPong is the best sports items in China.");

    private String description;

    private EnumTest3(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public static void main(String[] args) {
        for (EnumTest3 sport : EnumTest3.values()) {
            System.out.println(sport);
        }
    }
}

那么具体有什么用途?可以用来创建常量,这是我在公司的代码中看到的枚举类的用法。使用枚举的构造方法可以轻易的完成常量的设置,既有编码又有说明,是不是清晰?

public class EnumTest4 {

    public enum  Gender {

        MAN(0, "男性"), WOMAN(1, "女性"), UNKNOWN(2, "不明");

        private int code;

        private String msg;

        private Gender(int code, String msg) {
            this.code = code;
            this.msg = msg;
        }
    }

    public static void main(String[] args) {
        System.out.println(Gender.MAN.code);
    }
}

神奇的values()

枚举的values方法非常特殊,你找不到它的源码,好像它是无中生有的。
这个案例通过比较枚举子类Software和枚举父类Enum的所有方法,得出结论:Software类拥有Enum类所有的方法,但前者还拥有后者没有的values方法,这个方法是编译器静态加上去的。

enum Software {
    QQ, WECHAT, DUOKAN
}

public class EnumTest7 {

    public static List<String> analyze(Class<?> enumClass) {
        System.out.println("---------------------------");
        System.out.println("泛型接口:");
        for (Type t : enumClass.getGenericInterfaces()) {
            System.out.println(t);
        }

        System.out.println("父类:");
        // class java.lang.Enum
        System.out.println(enumClass.getSuperclass());

        System.out.println("方法:");
        List<String> methods = new ArrayList<>();
        for (Method m : enumClass.getMethods()) {
            methods.add(m.getName());
        }
        System.out.println(methods);
        System.out.println("---------------------------");
        return methods;
    }

    public static void main(String[] args) {
        List<String> softwareMethods = analyze(Software.class);
        List<String> enumMethods = analyze(Enum.class);

        System.out.println("子类是否有父类所有的方法:" + softwareMethods.containsAll(enumMethods));
        System.out.println("除了父类的方法,子类还有哪些?");
        softwareMethods.removeAll(enumMethods);
        System.out.println(softwareMethods);  // values
    }

}

我们再来看一个案例,将枚举子类向上转型为父类,我们发现父类无法调用values方法。但Class类提供了一个getEnumConstants方法,用来获取枚举数组,达到类似values的效果。

enum Song {
    YESTERDAY,
    HEY_JUDY
}

public class EnumTest8 {

    public static void main(String[] args) {
        Enum e = Song.YESTERDAY;
        // 编译错误,因为values是enum独有的,Enum没有,只能使用getEnmuConstants获取
//        e.values();
        for (Enum en : e.getClass().getEnumConstants()) {
            System.out.println(en);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/cblstc/article/details/88820547