刚才写完了代码,自测的时候,出现了NPE问题。

排查的时候发现是Lombok的坑,以前也遇到过,所以觉得有必要过来记录一下。

我先描述一下现象,我的代码里面订单服务A 需要调用缓存服务B,服务B就是一个Bean,使用方式是这样的:

class ServiceA {//使用 Lombok 提供的setter@Setterprivate ServiceB bXCacheService;public Data getData() {//这里出现了NPE问题bXCacheService.getSomeThing();}
}

这个问题使用Lombok 的同学可能有人遇到过,我用的是蚂蚁的Sofa,Spring也是类似的,

先说下bean初始化过程,是通过反射,调用set 方法初始化bean,下面代码是我截取的部分代码:Spring 中的初始化bean方法

public void setValue(final Object object, Object valueToApply) throws Exception {//获取write方法,实际就是setXXX方法final Method writeMethod = this.pd.getWriteMethod();if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {writeMethod.setAccessible(true);return null;}});} else {writeMethod.setAccessible(true);}}final Object value = valueToApply;if (System.getSecurityManager() != null) {} else {// 通过反射 用set 方法注入属性writeMethod.invoke(getWrappedInstance(), value);}
}

问题就出在 Sofa 拼接 bean 变量 set 方法的方式,例如:如果我们希望初始化的 bean 名称为 cacheService,那么 Sofa 拼接的 set 方法为 setCacheService,也就是set + 变量(首字母大写+剩余字符)。

但是如果 bean 名称是:tCacheService,bean 首字母小写,第二次字符是大写,那 set 方法就变成了:settCacheService,当第二个字符是大写的时候,set 不会设置变量 t 为大写 T。

但是 Lombok 不是这样,Lombok 的setter注解实现机制,会让 tCacheService 的 setter 方法变成 setTCacheService(), 所以bean初始化的时候会找不到 WriteMethod,bean注入失败,报NPE问题。

解决方法

解决方法要么调整bean的命名方式,不要让第二个字符是大写,要么改变这种变量不使用Lombok 注入,使用Idea / Eclipse 生成的setter 方法。

也算是Lombok 和 Idea 生成 setter 方法的区别,一般框架、中间件更偏向 Idea 的这种set 变量方式。

另一个需要注意的问题

还有一个不只是Lombok 要注意的点,就是boolean 类型的变量严禁使用 is 开头,因为无论是Lombok 还是Idea 默认生成的get 方法都是is打头,丢掉多余的is,set方法去掉is,可能引发非预期的问题,例如变量 boolean isOpen 和 变量 boolean open 变量的get方法名是一样的:isOpen(); set 方法都是 setOpen(boolean isOpen);

private boolean isOpen;public boolean isOpen() {return isOpen;
}public void setOpen(boolean open) {isOpen = open;
}

常规编程规范里面会让返回值是 boolean 变量的方法名以 is开头,但是变量本身不带is。

// 开火开关  -- 集中参数中心配置项
private String fireSwitch; public boolean isOpenFire() {return StringUtils.equalsIgnoreCase( "TRUE", fireSwitch);
}

往期推荐

Java中List排序的3种方法!

面试官:元素排序Comparable和Comparator有什么区别?

面试官:HashSet是如何保证元素不重复的?

小心Lombok用法中的坑相关推荐

  1. 小心 Enum Parse 中的坑

    小心 Enum Parse 中的坑 Intro 最近使用枚举的时候,踩了一个小坑,分享一下,主要是枚举从 int 值转成枚举时可能会遇到 Sample 来看下面的示例: 首先定义一个枚举: publi ...

  2. golang中container/list包中的坑

    转载地址:golang中container/list包中的坑 - Go语言中文网 - Golang中文社区 golang中list包用法可以参看golang中container/list包用法_che ...

  3. Vue+Element el-table属性row-class-name用法及踩坑

    el-table属性row-class-name用法及踩坑 需求前提:想要给表格的某一行加上不同的background,用来区分当前行的状态 根据官方给出的文档官方文档 在el-table中绑定自定义 ...

  4. (四)Asp.net web api中的坑-【api的返回值】

    (四)Asp.net web api中的坑-[api的返回值] 原文:(四)Asp.net web api中的坑-[api的返回值] void无返回值 IHttpActionResult HttpRe ...

  5. JDK中的坑:JDK中这些方法的bug你不要踩

    点击关注公众号,Java干货及时送达 图片来源:白夜追凶 前言: jdk作为我们每天必备的调用类库,里面大量提供了基础类供我们使用.可以说离开jdk,我们的java代码寸步难行,jdk带给我们的便利可 ...

  6. C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题

    C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题 参考文章: (1)C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题 ( ...

  7. 决策树python建模中的坑 :ValueError: Expected 2D array, got 1D array instead:

    决策树python建模中的坑 代码 #coding=utf-8 from sklearn.feature_extraction import DictVectorizerimport csvfrom ...

  8. 小心VB.NET中的除运算符/和/

    小心VB.NET中的除运算符"/"和"/" VB.NET中除运算符有两种,普通除"/"和整数除"/",如果我们写程序时不 ...

  9. Compound Words UVA - 10391(c++用法中substr函数用法+map实现)

    题意: 给出字典中一堆单词,单词的输入方式是以字典序输入的.问:在这一堆单词中,有那些单词是通过其它两个单词组合而来的.按字典序升序输出这些单词. 题目: You are to find all th ...

最新文章

  1. 精确分割和筛选音频从长的音频中
  2. 杭电2669拓展欧几里得
  3. 图解javascript中this指向
  4. 【Microstation】三维建模基础及软件入门到精通实验教程目录
  5. Quagga:开源的基于Zebra实现了RIP, OSPF, BGP的动态路由软件
  6. 没项目经验难就业?推荐你参加“大学生就业特训营” | 100 个免费名额,先到先得!...
  7. js函数中变量声明提前
  8. eclipse下彻底删除SVN插件
  9. 由JavaScript版迷宫游戏引出Java版迷宫地图生成器
  10. 18.10.20日报
  11. win10分屏设置壁纸+获取win10锁屏壁纸
  12. 区分LPCTSTR和LPTSTR和char *
  13. trinity运行原理及常见报错(一)
  14. RockChip Android平台抓取android trace的windows环境搭建
  15. 苹果iPad2充不上电的问题
  16. 三级管的三种工作状态
  17. 基于四元素法的捷联惯导姿态更新算法
  18. C# + Ext.Net打印
  19. 动态数据库工具——Database Inspector
  20. Springboot+vue项目音乐网站与分享平台

热门文章

  1. 倩女幽魂服务器维护时间,9月5日在线维护公告
  2. java 导出bcp文件格式_使用BCP导出导入数据
  3. python selenium对象怎么序列化_python selenium爬取斗鱼
  4. HTML5中本地储存概念是什么,什么优点 ,与cookie有什么区别?
  5. proxmox集群节点崩溃处理
  6. 入门系列之在Ubuntu 16.04使用Buildbot建立持续集成系统
  7. 如何将对象拼接成get传值的形式
  8. Keepalived 做负载均衡(简单实例)
  9. mongoDB 使用手册
  10. eclispe快捷键