美文网首页
Java的不可变类(缓存实例)

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

作者: cuzz_ | 来源:发表于2018-04-03 23:32 被阅读0次

    不可变类

    不可变类的意思是在创建该类的实例后,该实例的实例变量是不可以改变的。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
        }
    }
    

    相关文章

      网友评论

          本文标题:Java的不可变类(缓存实例)

          本文链接:https://www.haomeiwen.com/subject/rhvchftx.html