zoukankan      html  css  js  c++  java
  • Java> Java核心卷读书笔记

    引例

    当一个变量只能在一个有限集合内取值时,可以考虑使用枚举类型。比如,衣服尺寸分别编码为S、M、L、X,如果int数字1~4表示这4个编码,可能会出现一些问题:例如,衣服尺寸变量可能为0或者>4的数字,但是程序可能还不清楚含义。
    对于这种情况,可以定义枚举类型,表示衣服尺寸所有可能编码
    enum Size{SMALL, MEDIUM, LARGE, EXTRA_LARGE}
    声明变量表示一件衣服尺寸为M
    Size s = Size.MEDIUM
    这样,衣服尺寸就只能是枚举类型的枚举值,没有任何值用null表示。


    定义枚举类enum

    定义一个枚举类型实际上也是定义一个类,所有枚举类型都继承自Enum类。

    public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }
    

    既然枚举类型Size也是类,那是为什么没有构造器、方法和域呢?
    因为所有的枚举类都继承自Enum类,子类使用Java编译器提供的缺省构造器。作为枚举类型,主要目的是提供对枚举值的支持,如果单纯使用类的功能,更建议用普通class而非enum。
    如果需要使用显示构造器,也是可以的,比如

    // 使用构造器的枚举类
    public enum Size {
          SMALL("S"),
          MEDIUM("M"),
          LARGE("L"),
          EXTRA_LARGE("XL");
    
          private String abbreviation; // 名称自定义
          Size(String abbreviation) {
                this.abbreviation = abbreviation;
          }
    
          public String getAbbreviation() {
                return abbreviation;
          }
    }
    

    枚举类型的使用

    获取枚举常量名

    获取单个枚举常量名
    String t = Size.SMALL.toString(); // 获取枚举常量名 'SMALL'

    获取所有枚举常量

    Size[] values = Size.values(); // values是包含Size.SMALL, Size.MEDIUM, Size.LARGE, Size.EXTRA_LARGE的数组
    
    // 打印每个枚举常量名
    for(Size size: values) {
          System.out.println(size);
    }
    

    枚举名 -> 枚举常量

    从枚举常量名构建枚举变量
    Size s = Enum.valueOf(Size.class, "SMALL"); // valueOf是toString逆


    比较枚举类型

    比较两个枚举类型变量是否相等,使用 “==”,而不要使用“equals”。

    Size s1 = Size.MEDIUM;
    Size s2 = Size.LARGE;
    if(s1 == s2) 
          System.out.println("s1 == s2");
    else System.out.println("s1 ≠ s2");
    

    获取枚举常量出现位置

    可以利用Enum的orinal()方法获取枚举常量在定义中出现位置。枚举常量位置值从0开始,逐渐递增。
    枚举常量值无法通过像C那样通过设置enum{SMALL=1, MEDIUM, LARGE, EXTRA_LARGE}修改,通过API只能获取枚举常量在定义中出现位置顺序,而不能修改枚举值本身的值。

    // 枚举类型Size定义
    public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }
    
    Size s1 = Size.SMALL;
    int a = s1.ordinal(); // a = 0, 对应枚举常量Size.SMALL在定义中的出现顺序
    

    枚举类与单例模式

    单例模式需要实现的目标是:创建只有一个实例引用(或指针)共享使用,单例模式3个特点:

    1. 单例类构造方法私有;
    2. 单例类实例变量引用唯一并且私有化;
    3. 单例类提供给其他对象这一私有化实例引用(如getInstance);

    单例模式还需要关注的点:

    1. 是否延迟实例化;
    2. 是否多线程安全;

    方式一:利用枚举类型直接构造单例类
    这种方式利用了枚举类型只会装载一次的特性,等同于饿汉式,虽然线程安全,不过没有延迟实例化。

    /**
    * 延迟实例化:否
    * 多线程安全:是 
    */
    public enum User{
          INSTANCE;
          private User() {
          }
    
          public static  User getInstance() {
                return User.INSTANCE;
          }
    }
    
    // 等价于饿汉式
    public class User{
          private static User instance = new User();
          private User() {}
          
          public static User getInstance() {
                return instance;
          }
    }
    

    方式二:枚举类作为单例类的内部类
    利用枚举类只会


    参考

    1. 枚举实现单例模式
    2. 菜鸟教程-单例模式
  • 相关阅读:
    Redis持久化
    Java多线程面试题
    Spring学习总结(1)-注入方式
    SpringCloud常用注解
    Linux安装Redis
    Linux系统安装MySQL
    [转]Java CPU 100% 排查技巧
    ImportError: attempted relative import with no known parent package
    python出现Non-ASCII character 'xe6' in file statistics.py on line 19, but no encoding declared错误
    10个不为人知的 Python 冷知识
  • 原文地址:https://www.cnblogs.com/fortunely/p/14081930.html
Copyright © 2011-2022 走看看