最近做项目出现一个java.lang.StackOverflowError异常解决办法。
经过试验,两种解决方式
原因
StackOverflowError是由于当前线程的栈满了 也就是函数调用层级过多导致。
比如死递归。
如:
public String homePage(){
this.findAllNews();
return “shouye”;
}
代码复现
ajax请求需要返回这个对象
public class QueryBusinessSubDTO {
List<GoodsBusinessSub> listSub;
List<City> listArea;
public List<GoodsBusinessSub> getListSub() {
return listSub;
}
public void setListSub(List<GoodsBusinessSub> listSub) {
this.listSub = listSub;
}
public List<City> getListArea() {
return listArea;
}
public void setListArea(List<City> listArea) {
this.listArea = listArea;
}
}
public void getDTO() {
try {
List<GoodsBusinessSub> list = GoodsService.getBusinessSub();
QueryBusinessSubDTO dtp = new QueryBusinessSubDTO();
dtp.setListSub(list);
if (Long.valueOf(prov) > 0) {
List<City> listArea = CityService.getArea(Integer.valueOf(prov));
dtp.setListArea(listArea);
}
Gson gson = new Gson();
response.setCharacterEncoding("utf-8");
response.getWriter().print(gson.toJson(dtp));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
由于GoodsBusinessSub里存在有调用其他对象
private GoodsBusiness goodsBusiness;
public GoodsBusiness getGoodsBusiness() {
return goodsBusiness;
}
而对象GoodsBusiness里由存在其他的调用
public GoodsBusiness getGoodsBusinessBill() throws Exception {
return GoodsService.getGoodsBusiness(goodsBusinessBillId);
}
很明显,①:调用过于深入,②存在重复调用问题
解决方案
方案一:
比较简单
由于对象GoodsBusinessSub存在重复调用问题,而前端需要的数据属性只有:id,code,name
所以针对GoodsBusinessSub提取一个简单的DTO
@Data
public class GoodsBusinessSubDTO {
private Long id;
private String name;//门店简称
private String code;//门店编号
}
其他的方法依次替换掉即可
方案二、
利用GsonBuilder的ExclusionStrategy()接口,
实现类里面的属性排除
public class CommExclusionStrategy implements ExclusionStrategy{
/**
*要排除的字段
*/
@Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
String name = fieldAttributes.getName();
if (name.equals("prov") || name.equals("area")
|| name.equals("city") || name.equals("goodsBusiness"))
return true;
else
return false;
}
/**
*要排除的对象
*/
@Override
public boolean shouldSkipClass(Class<?> aClass) {
if (aClass.equals(GoodsBusiness.class))
return true;
else
return false;
}
}
总结
开发时,因保持类的纯洁性,防止循环调用和深层调用出现