枚举类的理解

枚举类

Enum类

//com.insanus.EnumClass.java
package com.insanus;
public class EnumClass {
    public static void main(String[] args) {
        for(TryEnum i: TryEnum.values()) {
            System.out.println(i);
            //values()返回enum实例的数组
        }
        //关于Enum的静态方法valueOf
        //static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
        TryEnum x = Enum.valueOf(TryEnum.class, "One");
        TryEnum y = TryEnum.valueOf("One");
        System.out.println(x == y);
        //这里显示是True

    }
}

enum TryEnum {
    One, Two
}/* Output:
One
Two
True
*///:~

因为Enum类中并没有values方法
所以我们来探讨一下values的神秘之处

//com.insanus.Values.java
import java.lang.reflect.Method;
import java.util.Set;
import java.util.TreeSet;

public class Values {
    public static void main(String[] args) {
        Class t = Enum.class;
        Class i= TryEnum.One.getClass();
        Set<String> temp = new TreeSet<>();
        for (Method in: t.getMethods()) {
            temp.add(in.getName());
        }
        for (Method in: i.getMethods()) {
            if(!temp.contains(in.getName()))
                System.out.println(in.getName() + "\n" + in.toString());
        }
    }
}

enum TryEnum {
    One
}/* Output:
values
public static com.insanus.TryEnum[] com.insanus.try_module.TryEnum.values()
*///:~

我们观察到,values并不是Enum的方法,但是在创建enum实例的时候,却出现了这个方法。可以推导出的是,这个values方法是编译器添加的静态方法。

我们写了一小段代码测试一下。

enum TryEnum {
    One;
    public TryEnum[] test() {
        return values();
    }
}

通过

static enum

//com.insanus.EnumClass1.java
package com.insanus;
public enum EnumClass1 {
    One
}

//com.insanus.TryEnum1.java
package com.insanus;
import static com.insanus.EnumClass1.*;
public TryEnum1 {
    public static void main(String[] args) {
        EnumClass1 t = One;
    }
}

enum添加新方法

因为enum可以当做一个特殊的类,所以可以添加和覆盖方法。甚至可以添加main。

//com.insanus.MethodEnum.java
package com.insanus;
public enum MethodEnum {
    One;
    //注意,不能没有添加序列(singleton的enum实现)
    public static void main(String[] args) {
        System.out.println("From Enum");
    }
}

switch和enum

//com.insanus.SwitchEnum.java
package com.insanus;
public enum SwitchEnum {
    One, Two;
    public static void main(String[] args) {
        SwitchEnum i = SwitchEnum.Two;
        switch(i) {
            case One:
                System.out.println("One");
                break;
            case Two:
                System.out.println("Two");
                break;
        }
    }
}/* Output:
Two
*///:~

使用接口组织枚举

//com.insanus.Values1.java
package com.insanus;
public class Values1 {
    public static void main(String[] args) {
        TryEnum1 i = TryEnum1.One.ONE;
    }
}
//嵌套接口
interface TryEnum1 {
    enum One implements TryEnum1 {
        ONE, TWO
    }
    enum Two implements TryEnum1 {
        THREE
    }
}

解释EnumSet和EnumMap的工作原理

EnumSet
从上面的文档,我们多少能猜的出。EnumSet利用了enum的“单例”特性,当每次添加进一个enum,就为其创造实例。

//com.insanus.TestEnumSet.java
package com.insanus;
public class TestEnumSet {
    public static void main(String[] args) {
        EnumSet<TestEnum> i = EnumSet.noneOf(TestEnum.class);
        i.add(TestEnum.Two);
        i.add(TestEnum.Two);
        System.out.println(i);
    }
}

enum TestEnum {
    One, Two;
}/* Output:
[Two]
*///:~

EnumMap
我们观察一下这句话
EnumMap<K extends Enum<K>,V>
应该和EnumSet的原理差不多

常量相关的方法

//com.insanus.EnumModel.java
package com.insanus;
public enum  EnumModel {
    One(5) {
        @Override
        void view() {
            System.out.println("来自One, id为" + super.type);
        }
    },
    Two(7) {
        @Override
        void view() {
            System.out.println("来自Two, id为" + super.type);
        }
    };
    abstract void view();
    private int type;
    EnumModel(int type) {
        this.type = type;
        System.out.println("父类构造器");
    }
    public static void main(String[] args) {
        EnumModel.One.view();
    }
}/* Output:
父类构造器
父类构造器
来自One, id为5
*///:~

我们观察到父类构造器被调用了两次,由此可以得出,enum为每个常量都生成了一个实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值