Java的不可变类(缓存实例)

不可变类

不可变类的意思是在创建该类的实例后,该实例的实例变量是不可以改变的。Java提java.lang.String类都是不可变类,当创建它们的实例后,实例的实例变量也是不可改变的。

如:

Double d = new Double(2.2);
String str = new String("cuzz");

如果需要创建一个自定义的不可变类,应具备以下几个规则

  • 使用privatefinal修饰符来修饰该类的成员变量
  • 提供带参数的构造器,用于根据传入参数来初始化类里的成员变量
  • 提供getter方法,不需要setter方法

下面定义一个不可变Adress类,程序把Address类的detail和postCode成员变量都使用private隐藏起来,并使用final修饰这两个成员变量,不允许其他方法修改这两个成员变量的值

public class Address {
    private final String detail;
    private final String postCode;
    // 在构造器里初始化两个实例变量
    public Address() {
        this.detail = "";
        this.postCode = "";
    }
    
    public Address(String detail, String postCode) {
        this.detail = detail;
        this.postCode = postCode;
    }
    
    // 仅为两个实例变量提供getter方法
    public String getDetail() {
        return this.detail;
    }
    
    public String getPostCode() {
        return this.postCode;
    }
    
    // 重新equeal方法
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        
        if (obj != null && obj.getClass() == Address.class) {
            Address address = (Address) obj;
            // 当detail和postCode同时相等时
            if (address.detail == detail && address.postCode == postCode) {
                return true;
            }
        }
        return false;
    }
    
    public int hashCode() {
        return detail.hashCode() + postCode.hashCode() * 31;
    }
}

缓存实例的不可变类

不可变类的实例状态不可以改变,可以很方便的被多个对象所共享,如果程序经常需要使用相同的不可变实例,可以考虑缓存这种不可变的实例。

public class CacheImmutable {
    private static int MAX_SIZE = 10;
    // 使用数组来缓存已有的实例
    private static CacheImmutable[] cache = new CacheImmutable[MAX_SIZE];
    // 记录缓存实例在缓存的位置   cache[pos-1]是最新的实例
    private static int pos = 0;
    private final String name;
    
    private CacheImmutable(String name) {
        this.name = name;
    }
    
    private String getName() {
        return name;
    }
    
    public static CacheImmutable valueOf(String name) {
        // 遍历所有的对象
        for (int i = 0; i < MAX_SIZE; i++) {
            // 如果已有相同的实例  则返回该缓存的实例
            if (cache[i] != null && cache[i].getName().equals(name)) {
                return cache[i];
            }
        }
        // 如果缓存池已满
        if (pos == MAX_SIZE) {
            // 把缓存的第一个对象覆盖  把刚刚生成的对象放在缓存池最开始
            pos = 0;
            cache[pos++] = new CacheImmutable(name);
        }else {
            cache[pos++] = new CacheImmutable(name);
        }
        return cache[pos-1];
        

    }
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj != null && obj.getClass() == CacheImmutable.class) {
            CacheImmutable ci = (CacheImmutable) obj;
            return name.equals(ci.getName());
        }
        return false;
    }
}

测试类:

public class CacheImmutableTest {
    public static void main(String[] args) {
        CacheImmutable c1 = CacheImmutable.valueOf("cuzz");
        CacheImmutable c2 = CacheImmutable.valueOf("cuzz");
        System.out.println(c1 == c2 );   // 输出true
    }
}

与Java提供的java.lang.Integer类采用的相同的策略

public class IntegerCacheTest {
    public static void main(String[] args) {
        // 生成新的Integer对象
        Integer in1 = new Integer(6);
        // 生成新的Integer对象  并缓存该对象
        Integer in2 = Integer.valueOf(6);
        // 直接从缓存中取出Integer对象
        Integer in3 = Integer.valueOf(6);
        System.out.println(in1 == in2);  // false
        System.out.println(in2 == in3);  // true
        // 由于Integer只缓存-128~127之间
        Integer in4 = Integer.valueOf(200);
        Integer in5 = Integer.valueOf(200);
        System.out.println(in4 == in5);   // false
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,735评论 18 399
  • 一、Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计...
    子非鱼_t_阅读 9,869评论 1 44
  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 7,652评论 0 11
  • 在我参加工作若干年之后,始终觉得人这一生,运动和学习将是永恒的伴随,运动使人健康,学习催人进步,且乐趣多多,积极向...
    漫步海滩521阅读 3,134评论 0 0
  • 2018年1月12日 星期五 晴 昨天和熊老师讨论了孩子读书的问题,熊老师家宝贝比我家二宝大几个月,现在每天自己看...
    Viki和两宝共成长阅读 1,414评论 0 1

友情链接更多精彩内容