Guava LoadingCache不能缓存null值
2020-02-08 16:01:50来源:博客园 阅读 ()
Guava LoadingCache不能缓存null值
测试的时候发现项目中的LoadingCache没有刷新,但是明明调用了refresh方法了。后来发现LoadingCache是不支持缓存null值的,如果load回调方法返回null,则在get的时候会抛出异常。
通过几个例子开看这个问题:
public void test_loadNull() {
LoadingCache<String, String> stringCache = CacheBuilder.newBuilder()
.maximumSize(10)
.build(new CacheLoader<String, String>() {
@Override
public String load(String s) throws Exception {
System.out.println("xx");
if (s.equals("hello"))
return "world";
else
return null;
}
});
try {
System.out.println(stringCache.get("hello"));
// get触发load,load返回null则抛出异常:
// com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key other_key.
System.out.println(stringCache.get("other_key"));
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public void test_loadNullWhenRefresh() {
LoadingCache<String, String> stringCache = CacheBuilder.newBuilder()
.maximumSize(10)
.build(new CacheLoader<String, String>() {
int i = 0;
@Override
public String load(String s) throws Exception {
if (i == 0) {
i++;
return "world";
}
return null;
}
});
try {
System.out.println(stringCache.get("hello"));
System.out.println(stringCache.get("hello"));
// refresh的时候,如果load函数返回null,则refresh抛出异常:
// Exception thrown during refresh
// com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key hello.
stringCache.refresh("hello");
System.out.println(stringCache.get("hello"));
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public void test_loadNullAfterInvalidate() {
LoadingCache<String, String> stringCache = CacheBuilder.newBuilder()
.maximumSize(10)
.build(new CacheLoader<String, String>() {
int i = 0;
@Override
public String load(String s) throws Exception {
if (i == 0) {
i++;
return "world";
}
return null;
}
});
try {
System.out.println(stringCache.get("hello"));
System.out.println(stringCache.get("hello"));
// invalidate不会触发load
stringCache.invalidate("hello");
// invalidate后,再次get,触发load,抛出异常:
// com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key hello.
System.out.println(stringCache.get("hello"));
} catch (ExecutionException e) {
e.printStackTrace();
}
}
public void test_loadThrowException() {
LoadingCache<String, String> stringCache = CacheBuilder.newBuilder()
.maximumSize(10)
.build(new CacheLoader<String, String>() {
@Override
public String load(String s) throws Exception {
if (s.equals("hello"))
return "world";
else
throw new IllegalArgumentException("only_hello");
}
});
try {
System.out.println(stringCache.get("hello"));
// get触发load,load抛出异常,get也会抛出封装后的异常:
// com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalArgumentException: only_hello
System.out.println(stringCache.get("other_key"));
} catch (ExecutionException e) {
e.printStackTrace();
}
}
所以如果你需要缓存“空”值,推荐的做法是使用Optional对象来封装结果:
public void test_loadUseOptional() {
LoadingCache<String, Optional<String>> stringCache = CacheBuilder.newBuilder()
.maximumSize(10)
.build(new CacheLoader<String, Optional<String>>() {
@Override
public Optional<String> load(String s) throws Exception {
if (s.equals("hello"))
return Optional.of("world");
else
return Optional.absent();
}
});
try {
Optional<String> hello = stringCache.get("hello");
if(hello.isPresent()) {
System.out.println(hello.get());
}
Optional<String> otherKey = stringCache.get("other_key");
if(otherKey.isPresent()){
System.out.println(otherKey.get());
}
} catch (ExecutionException e) {
e.printStackTrace();
}
}
如果你的场景中认为null是不存在的,那么你可以在load函数中抛出异常,这个异常会通过get抛出。
另外还有一个问题,如果是key==null呢?答案是直接抛出java.lang.NullPointerException
。Guava对于null是很不待见的。
参考资料
- [Google Guava] 3-缓存 | 并发编程网 – ifeve.com
http://ifeve.com/google-guava-cachesexplained/ - Guava Cache使用笔记 - 代码说-Let code talk - ITeye博客
http://bylijinnan.iteye.com/blog/2225074 - guava - How to avoid caching when values are null? - Stack Overflow
https://stackoverflow.com/questions/13379071/how-to-avoid-caching-when-values-are-null
本文独立博客地址:Guava LoadingCache不能缓存null值 | 木杉的博客
原文链接:https://www.cnblogs.com/mushan/p/12275555.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:并发编程之线程第二篇
- Mockito不能mock final类的解决办法 2020-05-16
- 什么情况下不能使用 Java 泛型 2020-05-12
- 那些你不能遗忘的多线程、并发及线程的基础问题 2020-04-30
- Java的外部类为什么不能使用private、protected进行修饰 2020-04-28
- 0318 guava并发工具 2020-03-19
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash