疑惑Guava中的Cache是如何做到“直接修改内存副本”的?

刚转JAVA,接触Guava,所以可能没有把问题描述的过于清楚,请见谅。

Guava中提供了Cache模块,下面的例子让我很困惑:

package me.kazaff;


import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import java.util.concurrent.TimeUnit;

public class Main {

    public static LoadingCache<String, Person> cache = CacheBuilder.newBuilder()
                                                .maximumSize(1000)
                                                .expireAfterAccess(10, TimeUnit.MINUTES)
                                                .build(new CacheLoader<String, Person>() {
                                                    @Override
                                                    public Person load(String s) throws Exception {

                                                        Person p = new Person();
                                                        p.setName(s);
                                                        p.setAge(0);
                                                        return p;
                                                    }
                                                });

    public static void main(String[] args) {
        try{

            Person p = cache.get("kazaff");
            p.setName("edisondik"); //直接修改对象

            System.out.println("object: " + p.getName());
            System.out.println("cache: " + cache.get("kazaff").getName());

        }catch (Exception e){
            System.out.println(e.getCause());
        }
    }
}

终端打印:

Object: edisondik
cache: edisondik

可以看到,我并没有在修改完对象后重新保存到缓存中,它是如何做到的?
给我的感觉就好像是cache.get直接返回的引用一样!

谁能给我解释一下呢?

阅读 7.1k
1 个回答

这个。。。 你从cache里拿到的是一个 对象实例的引用,始终指向同一个对象实例。
拿HashMap来存也是一样的。

@Test
public void dfasdf(){
    Map<String, Person> map = new HashMap<>();
    Person kazaff = new Person();
    kazaff.setName("kazaff");
    map.put("kazaff", kazaff);

    Person p = map.get("kazaff");
    p.setName("edisondik");
    System.out.println(map.get("kazaff").getName()); //get 'edisondik'
}

从cache拿两次得到同一个实例

@Test
public void mainTest() throws Exception {
    Person p = cache.get("kazaff");               
    Person p1 = cache.get("kazaff");
    assertTrue(p == p1);  // success
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题