我不是在这里问什么是空指针异常。我已经调试了项目并看到了空指针在哪里。我的项目流程是:
我的Api是:
package com.cache.api;
@Path("/myresource")
public class MyResource {
@Inject
private CacheHelper cacheHelper;
@Inject
private DtoPlan dtoPlan;
@GET
@Path("/putAllInDto")
@Produces(MediaType.APPLICATION_JSON)
public String putAllInDto() throws Exception {
CachePlan cf=CacheFactory.getPlan(PlanChooser.DTO);
cf.putInCache(); //data are loaded in DtoPlanImpl Class
MemberDTO md=cf.getMemberDtos(); //data comes from here with cf object
// MemberDTO md1=dtoPlan.getMemberDto(); //java.lang.NullPointerException when I use dtoPlan.memberDto();
//
// System.out.println(md.getMemberName());
return "insertedindto";
}
}
cachePlan接口为:
package com.cache.plan;
public interface CachePlan {
public void putInCache() throws ExecutionException, InterruptedException ;
public MemberDTO getMemberDtos() throws ExecutionException, InterruptedException ;
}
我的DtoPlanImpl.java类是。这里我需要实现新的接口 DtoPlan 。
package com.cache.impl;
@Stateless
public class DtoPlanImpl implements CachePlan,DtoPlan
{
private CacheManager cacheManager;
private Cache<String,MemberDTO> memberCache;
private static final String CACHE_MEMBER_DTO_PARAMETER="cache_member_dto_type";
private MemberService memberService = CDI.current().select(MemberService.class).get();
public DtoPlanImpl(){
System.getProperties().setProperty("java -Dnet.sf.ehcache.use.classic.lru", "true");
cacheManager= CacheManagerBuilder
.newCacheManagerBuilder().build();
cacheManager.init();
}
@Override
public void putInCache() {
System.out.println("putting data from dto");
memberCache = cacheManager
.createCache("cacheOfMemberCache", CacheConfigurationBuilder
.newCacheConfigurationBuilder(
String.class,MemberDTO.class,
ResourcePoolsBuilder.heap(1000000000)).withExpiry(Expirations.timeToLiveExpiration
(Duration.of(60000,
TimeUnit.SECONDS))));
memberCache.put(CACHE_MEMBER_DTO_PARAMETER,memberService.getMemberDTO());
MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
System.out.println(mD.getMemberName());
}
@Override
public MemberDTO getMemberDtos() {
MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
return mD;
}
@Override
public MemberDTO getMemberDto() throws ExecutionException, InterruptedException {
MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
return mD;
}
}
我的DtoPlan界面是:
public interface DtoPlan {
public MemberDTO getMemberDto() throws ExecutionException, InterruptedException;
}
所以问题是当我将CacheFactory cf用作:
MemberDTO md=cf.getMemberDtos(); //data comes from here with cf object
但是当我使用时:
MemberDTO md1=dtoPlan.getMemberDto(); //java.lang.NullPointerException
我调试了程序,并从出现空指针的地方开始可视化:
它来自第MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
行的此类DtoPlanImpl:
@Override
public MemberDTO getMemberDto() throws ExecutionException, InterruptedException {
MemberDTO mD=memberCache.get(CACHE_MEMBER_DTO_PARAMETER);
return mD;
}
在这里我从dtoPlan.getMemberDto();
调用的memberCache为null,但是当我从cf.getMemberDtos();
调用时,我正在获取数据。
答案 0 :(得分:0)
您正在memberCache
方法中初始化putInCache()
,而不是在构造函数中初始化。对于您的设计,您需要先将某些内容放入缓存中,然后才能检索某些内容。因此,可以在构造函数中对其进行初始化,也可以在其中 put 。
还要注意,默认情况下,Guice每次提供值时都会返回一个新实例。因此,您可能在将内容放入缓存中时使用一个实例,从而初始化memberCache
,而在检索数据时使用另一个实例,其中memberCache
为空。您可以使用@Singleton
注解在所有地方注入DtoPlan
的相同实例。
看起来您每次需要在其中添加新内容时都在创建一个新的缓存实例。因此,您将丢失先前存储的值。整个代码看起来有缺陷。