不一样的Java Enum

Emum是在Java5中引入的新特性,从那开始,它被广泛的用在不同的Java应用中,相比于C和C++的Enum,Java的Enum功能更加强大。但是很多开发人员暂时还没意识到它的强大之处,在Enum的一些细节问题上把握的还不到位。Enum的特性及相关资料可以整理出一本书也不为过,这里简单对Enum做个大概。主要讲解以下几个方面。

1.     Enum的介绍

2.     Enum的特性

3.     Enum的用法

4.     Enum的一些面试题

5.     Enum用法建议

什么是Enum

Enum是一个Java的关键字,用于表示一个固定的常用值。例如,每周的天数,每年的月数等。Enum是一种类型,就像Class和Interface可以用于定义一系列的Enum常量

Enum的特性

·        Enum常量隐式的加上了static和final,一旦被创建就无法修改

·        Enum提供了是类型安全的(type-safe)

·        Enum隐式的加上了values()方法,返回一个数组包含所有的Enum常量

·        两个Enum常量可以使用 ==equals()方法比较

·        Enum可以用在switch语句中,就像int,String。

·        Enum有自己的名称空间

·        Enum可以实现Java接口

·        可以在Enum中定义构造器

Enum的用法

1. Enum的声明,Enum可以声明在一个类之外或者在类内部,但是不能在方法中。

// 外部声明Enum
enum Color {
    RED,GREEN,BLUE;
}
public class Test
{
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
    }
}
//内部声明Enum
public class Test
{
    enum Color
    {
        RED, GREEN, BLUE;
    }
 
    public static void main(String[] args)
    {
        Color c1 = Color.RED;
        System.out.println(c1);
    }
}

2. 在创建Enum常量的时候可以指定值,但是这个时候你需要定义一个成员变量构造器。构造器必须是private的,不然会报编译错误。

public enum Currency {
    PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
    private int value;
 
    private Currency(int value) {
        this.value = value;
    }
}

3. 使用==equals比较两个enum
因为enum对象都是继承自Enum类的,可以看到Enum中的equals方法为。
建议使用==方法,直接比较应该比调用方法的速度更快一些。另外==号还能防止NullPointerException

    public final boolean equals(Object other) {
        return this==other;
    }

4. 对Enum进行排序的时候,使用compareTo方法。

    public final int compareTo(E o) {
        Enum<?> other = (Enum<?>)o;
        Enum<E> self = this;
        if (self.getClass() != other.getClass() && // optimization
            self.getDeclaringClass() != other.getDeclaringClass())
            throw new ClassCastException();
        return self.ordinal - other.ordinal;
    }

5.有两个新的集合类EnumMapEnumSet ,他们两个是对Set和Map的高性能实现,当有机会使用它们的时候,尽量使用它们。

Enum面试问题

1.    说说Enum的继承
所有的enums隐式的extend了java.lang.Enum类,因为一个类只能extend一个父亲,所以enum不能extend其它的类。
但是Enum可以实现许多接口

2.     Enum的values,ordinal,valueOf方法
enums默认有values(),ordinal()和valueOf()方法。
values()方法返回所有在enum中定义的常量值,以数组形式返回。
ordinal()方法返回每个常量的索引下标,就像数组的下标
valueOf()方法传入字符串参数,如果enum中存在对应字符串的常量值,则返回对应的enum常量

// 案例代码
enum Color
{
    RED, GREEN, BLUE;
}
 
public class EnumLearn
{
    public static void main(String[] args)
    {
 
        Color arr[] = Color.values();        
        for (Color col : arr)
        {
            System.out.println(col + " at index "
                    + col.ordinal());
        }
        System.out.println(Color.valueOf("RED"));
    }
}
 
//输出
RED at index 0
GREEN at index 1
BLUE at index 2
RED

3. Enum的构造器特性
enum
可以有构造器方法,它的构造器方法会在enum类型加载的时候,按常量的个数顺序的执行
我们不能直接创建enum对象,因此我们也不能直接调用enum的构造器方法,构造器方法必须是private的

//案例代码
enum AccountType implements Serializable,Cloneable
{
    SAVING, FIXED, CURRENT;
    private AccountType()
    {
        System.out.println("It is a account type");
    }
}
class EnumOne
{
    public static void main(String[]args)
    {
        System.out.println(AccountType.FIXED);
 
    }
}
//输出结果
It is a account type
It is a account type
It is a account type
FIXED

4. Enum的单例模式优缺点
参考《Effitive Java》,优点大于缺点,因为enum是线程安全的,因此我们无需考虑单例模式的双重检查。主要原因:

·        enum的单例模式简单

·        enum是线程安全的

·        enum的单例模式自己处理序列化 *

// Enum的单例模式 VS 传统双重检查的单例模式
//单例模式,仅需使用一行代码.
// EasySingleton.INSTANCE,enum中也可以写其他方法
public enum EasySingleton{
    INSTANCE;
}
 
//传统模式
public class DoubleCheckedLockingSingleton{
     private volatile DoubleCheckedLockingSingleton INSTANCE;
 
     private DoubleCheckedLockingSingleton(){}
 
     public DoubleCheckedLockingSingleton getInstance(){
         if(INSTANCE == null){
            synchronized(DoubleCheckedLockingSingleton.class){
                //  二次检查
                if(INSTANCE == null){
                    INSTANCE = new DoubleCheckedLockingSingleton();
                }
            }
         }
         return INSTANCE;
     }
}

5. Enum==equals的区别。
前面有提到。

6. 我们能使用构造方法创建enum实例吗?
不能,enum的构造方法必须是私有的。

Enum的用法建议

在能想到使用Enum的时候可以考虑使用Enum。

1.     使用Enum代替定义的相关int类型常量

2.     能用到EnumSet和EnumMap的时候使用它们,后面会再说明它们两个的用法

最后

看一些Java相关的面试题,发现Enum相关问题出现频率挺高的,在这里对enum用法做个整理。希望能帮助到大家



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值