南京百度快照优化排名,苏州seo关键词优化报价,泰安五险一金的工作最新招聘,工商注册需要准备什么材料刚才写完了代码#xff0c;自测的时候#xff0c;出现了NPE问题。排查的时候发现是Lombok的坑#xff0c;以前也遇到过#xff0c;所以觉得有必要过来记录一下。我先描述一下现象#xff0c;我的代码里面订单服务A 需要调用缓存服务B#xff0c;服务B就是一个Bean#x… 刚才写完了代码自测的时候出现了NPE问题。排查的时候发现是Lombok的坑以前也遇到过所以觉得有必要过来记录一下。我先描述一下现象我的代码里面订单服务A 需要调用缓存服务B服务B就是一个Bean使用方式是这样的class ServiceA {//使用 Lombok 提供的setterSetterprivate ServiceB bXCacheService;public Data getData() {//这里出现了NPE问题bXCacheService.getSomeThing();}
}这个问题使用Lombok 的同学可能有人遇到过我用的是蚂蚁的SofaSpring也是类似的先说下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 PrivilegedActionObject() {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 名称是tCacheServicebean 首字母小写第二次字符是大写那 set 方法就变成了settCacheService当第二个字符是大写的时候set 不会设置变量 t 为大写 T。但是 Lombok 不是这样Lombok 的setter注解实现机制会让 tCacheService 的 setter 方法变成 setTCacheService(), 所以bean初始化的时候会找不到 WriteMethodbean注入失败报NPE问题。解决方法解决方法要么调整bean的命名方式不要让第二个字符是大写要么改变这种变量不使用Lombok 注入使用Idea / Eclipse 生成的setter 方法。也算是Lombok 和 Idea 生成 setter 方法的区别一般框架、中间件更偏向 Idea 的这种set 变量方式。另一个需要注意的问题还有一个不只是Lombok 要注意的点就是boolean 类型的变量严禁使用 is 开头因为无论是Lombok 还是Idea 默认生成的get 方法都是is打头丢掉多余的isset方法去掉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是如何保证元素不重复的