刚才写完了代码,自测的时候,出现了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. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值
  2. 跨链Cosmos(6)ABCI 原理
  3. 第四章 Rails 背后的 Ruby
  4. Python SQLAlchemy --3
  5. Python工作笔记-解决python使用nohup后台运行重定向不输出问题
  6. 阻止电脑自动安装软件_坡解版wetool 安装条件-购买-老友网
  7. 【JDK】JDK源码分析-CountDownLatch
  8. 永久改变Win10命令提示符(cmd)字体
  9. Docker selenium Python 可靠的selenium Docker环境
  10. 低频声音功率放大器电子设计报告
  11. Kali 中文目录改英文目录
  12. 做外贸如何免费申请企业邮箱?
  13. 【hadoop】进阶篇一:MapReduce之Job的提交
  14. 电脑远程桌面连接怎么操作?
  15. VS2008 Pocket PC 2003 SE仿真程序上网设置
  16. VML实例及两个网站
  17. Microsoft Dynamics CRM Javascript定制表单左边导航栏
  18. 星星之火-52:6G十大领域关键技术
  19. Listener refused the connection with the following error: ORA-12519, TNS:no appr
  20. RISC-V CSR 相关指令集

热门文章

  1. c语言程序兔子反之问题,C语言解决兔子产子问题代码及解析
  2. 人工蜂群算法python_改进的人工蜂群算法解决聚类问题(在Python中的分步实现)...
  3. 找出占用cpu最高的线程
  4. C#浅拷贝与深拷贝区别
  5. In Compiler.php line 36: Please provide a valid cache path.
  6. C#中的Dictionary字典类介绍(转载)
  7. Windows 8.1 升级到专业版
  8. repadmin查看域控之间的复制状态
  9. 云计算的发展及应用--演讲用PPT
  10. RAC 之 RMAN 备份