认识Lombok的坑
java基础教程栏目为大家介绍认识Lombok的坑,好用。
序言
去年在项目当中引入了Lombok插件,着实解放了双手,代替了一些重复的简单工作(Getter,Setter,toString等方法的编写),但是,在使用的过程当中,也发现了一些坑,开始的时候并没有察觉到是Lombok的问题,后来跟踪了对应的其他组件的源码,才发现是Lombok的问题!
Setter-Getter方法的坑
问题发现
我们在项目当中主要使用Lombok的Setter-Getter方法的注解,也就是组合注解@Data,但是在一次使用Mybatis插入数据的过程当中,出现了一个问题,问题描述如下:
我们有个实体类: @Data public class NMetaVerify{ private NMetaType nMetaType; private Long id; ....其他属性 }复制代码
当我们使用Mybatis插入数据的时候,发现,其他属性都能正常的插入,但是就是nMetaType属性在数据库一直是null.
解决
当我debug项目代码到调用Mybatis的插入SQL对应的方法的时候,我看到NMetaVerify对象的nMetaType属性还是有数据的,但是执行插入之后,数据库的nMetaType字段就是一直是null,原先我以为是我的枚举类型写法不正确,看了下别的同样具有枚举类型的字段,也是正常能插入到数据库当中的,这更让我感觉到疑惑了.于是,我就跟踪Mybatis的源码,发现Mybatis在获取这个nMetaType属性的时候使用了反射,使用的是getxxxx方法来获取的,但是我发现nMetaType的get方法好像有点和Mybatis需要的getxxxx方法长的好像不一样.问题找到了!
原因
Lombok对于第一个字母小写,第二个字母大写的属性生成的get-set方法和Mybatis以及idea或者说是Java官方认可的get-set方法生成的不一样:
#Lombok生成的Get-Set方法 @Data public class NMetaVerify { private Long id; private NMetaType nMetaType; private Date createTime; public void lombokFound(){ NMetaVerify nMetaVerify = new NMetaVerify(); nMetaVerify.setNMetaType(NMetaType.TWO); //注意:nMetaType的set方法为setNMetaType,第一个n字母大写了, nMetaVerify.getNMetaType(); //getxxxx方法也是大写 } }复制代码
#idea,Mybatis,Java官方默认的行为为: public class NMetaVerify { private Long id; private NMetaType nMetaType; private Date createTime; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public NMetaType getnMetaType() {//注意:nMetaType属性的第一个字母小写 return nMetaType; } public void setnMetaType(NMetaType nMetaType) {//注意:nMetaType属性的第一个字母小写 this.nMetaType = nMetaType; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } }复制代码
Mybatis(3.4.6版本)解析get-set方法获取属性名字的源码:
package org.apache.ibatis.reflection.property; import java.util.Locale; import org.apache.ibatis.reflection.ReflectionException; /** * @author Clinton Begin */ public final class PropertyNamer { private PropertyNamer() { // Prevent Instantiation of Static Class } public static String methodToProperty(String name) { if (name.startsWith("is")) {//is开头的一般是bool类型,直接从第二个(索引)开始截取(简单粗暴) name = name.substring(2); } else if (name.startsWith("get") || name.startsWith("set")) {//set-get的就从第三个(索引)开始截取 name = name.substring(3); } else { throw new ReflectionException("Error parsing property name '" + name + "'. Didn't start with 'is', 'get' or 'set'."); } //下面这个判断很重要,可以分成两句话开始解释,解释如下 //第一句话:name.length()==1 // 对于属性只有一个字母的,例如private int x; // 对应的get-set方法是getX();setX(int x); //第二句话:name.length() > 1 && !Character.isUpperCase(name.charAt(1))) // 属性名字长度大于1,并且第二个(代码中的charAt(1),这个1是数组下标)字母是小写的 // 如果第二个char是大写的,那就直接返回name if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) { name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);//让属性名第一个字母小写,然后加上后面的内容 } return name; } public static boolean isProperty(String name) { return name.startsWith("get") || name.startsWith("set") || name.startsWith("is"); } public static boolean isGetter(String name) { return name.startsWith("get") || name.startsWith("is"); } public static boolean isSetter(String name) { return name.startsWith("set"); } }复制代码
Mybatis解析get-set方法为属性名字测试
@Test public void foundPropertyNamer() { String isName = "isName"; String getName = "getName"; String getnMetaType = "getnMetaType"; String getNMetaType = "getNMetaType"; Stream.of(isName,getName,getnMetaType,getNMetaType) .forEach(methodName->System.out.println("方法名字是:"+methodName+" 属性名字:"+ PropertyNamer.methodToProperty(methodName))); } #输出结果如下: 方法名字是:isName 属性名字:name 方法名字是:getName 属性名字:name 方法名字是:getnMetaType 属性名字:nMetaType //这个以及下面的属性第二个字母都是大写,所以直接返回name 方法名字是:getNMetaType 属性名字:NMetaType复制代码
解决方案
1.修改属性名字,让第二个字母小写,或者说是规定所有的属性的前两个字母必须小写 2.如果数据库已经设计好,并且前后端接口对接好了,不想修改,那就专门为这种特殊的属性使用idea生成get-set方法复制代码
@Accessor(chain = true)注解的问题
问题发现
在使用easyexcel(github.com/alibaba/eas…) 导出的时候,发现以前的实体类导出都很正常,但是现在新加的实体类不正常了,比对了发现,新加的实体类增加了@Accessor(chain = true)注解,我们的目的主要是方便我们链式调用set方法:
new UserDto() .setUserName("") .setAge(10) ........ .setBirthday(new Date());复制代码
原因
easyexcel底层使用的是cglib来做反射工具包的:
com.alibaba.excel.read.listener.ModelBuildEventListener 类的第130行 BeanMap.create(resultModel).putAll(map); 最底层的是cglib的BeanMap的这个方法调用 abstract public Object put(Object bean, Object key, Object value);复制代码
但是cglib使用的是Java的rt.jar里面的一个Introspector这个类的方法:
# Introspector.java 第520行 if (int.class.equals(argTypes[0]) && name.startsWith(GET_PREFIX)) { pd = new IndexedPropertyDescriptor(this.beanClass, name.substring(3), null, null, method, null); //下面这行判断,只获取返回值是void类型的setxxxx方法 } else if (void.class.equals(resultType) && name.startsWith(SET_PREFIX)) { // Simple setter pd = new PropertyDescriptor(this.beanClass, name.substring(3), null, method); if (throwsException(method, PropertyVetoException.class)) { pd.setConstrained(true); } }复制代码
解决方案
1.去掉Accessor注解 2.要么就等待easyexcel的作者替换掉底层的cglib或者是其他,反正是支持获取返回值不是void的setxxx方法就行复制代码
相关免费学习推荐:java基础教程
Atas ialah kandungan terperinci 认识Lombok的坑. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Panduan profesional: Nasihat pakar dan langkah-langkah untuk memasang pemalam Lombok dalam Eclipse, contoh kod khusus diperlukan Ringkasan: Lombok ialah perpustakaan Java yang memudahkan penulisan kod Java melalui anotasi dan menyediakan beberapa alatan berkuasa. Artikel ini akan memperkenalkan pembaca kepada langkah-langkah cara memasang dan mengkonfigurasi pemalam Lombok dalam Eclipse, dan menyediakan beberapa contoh kod khusus supaya pembaca boleh memahami dan menggunakan pemalam Lombok dengan lebih baik. Muat turun pemalam Lombok dahulu, kami perlukan

Mula Pantas: Tutorial ringkas untuk memasang pemalam Lombok dalam Eclipse, yang memerlukan contoh kod khusus Dalam proses membangunkan projek Java, Lombok sering digunakan sebagai pemalam praktikal. Lombok boleh membantu kami memudahkan kod Java, mengurangkan penulisan kod boilerplate dan meningkatkan kecekapan pembangunan. Artikel ini akan memperkenalkan anda kepada cara memasang dan mengkonfigurasi pemalam Lombok dalam Eclipse, dan memberikan contoh kod khusus. Langkah 1: Muat turun pemalam Lombok Mula-mula, kita perlu memuat turun pemalam Lombok dari laman web rasmi Lombok

LombokLombok boleh memudahkan kod java dalam bentuk anotasi mudah, dengan itu meningkatkan kecekapan pembangunan pembangun. Ia sendiri adalah perpustakaan kod Java yang sangat baik Ia menggunakan gula sintaksis oportunistik untuk memudahkan pengekodan Java dan menyediakan cara untuk menyelaraskan kod Java. Kelas Java yang sering perlu ditulis semasa pembangunan web memerlukan masa untuk menambah pengambil/penetap, pembina, equals dan kaedah lain yang sepadan. Apabila terdapat banyak atribut, akan terdapat sejumlah besar kaedah getter/setter Ini adalah sangat panjang dan tidak mempunyai banyak kandungan teknikal Setelah atribut diubah suai, mudah untuk terlupa untuk mengubah suai kaedah yang sepadan.

Panduan Lengkap: Cara Memasang Pemalam Lombok untuk Eclipse, Contoh Kod Khusus Diperlukan Pengenalan: Eclipse ialah persekitaran pembangunan bersepadu (IDE) yang digunakan secara meluas untuk pembangunan Java. Lombok ialah perpustakaan Java yang boleh mengautomasikan beberapa kod yang membosankan untuk meningkatkan kecekapan pembangunan. Artikel ini akan memperincikan cara memasang pemalam Lombok dalam Eclipse dan memberikan contoh kod khusus. Langkah 1: Muat turun pemalam Lombok, buka Eclipse dan pilih "Bantuan

Petua praktikal: Cara memasang pemalam Lombok dalam Eclipse dengan mudah, contoh kod khusus diperlukan Dalam pembangunan Java harian, kami sering menggunakan Eclipse sebagai persekitaran pembangunan bersepadu utama. Dalam pembangunan sebenar, kami mungkin menghadapi beberapa operasi yang membosankan, seperti penulisan manual kaedah Getter dan Setter. Untuk memudahkan operasi ini, kami boleh menggunakan pemalam Lombok untuk membantu kami menjana kod ini secara automatik. Begini cara untuk memasang dan mengkonfigurasinya dengan mudah dalam Eclipse

Apakah Lombok? Lombok ialah perpustakaan Java yang direka untuk mengurangkan usaha pembangunan kod. Ia menyediakan beberapa anotasi mudah untuk menghapuskan kod templat yang kembung dalam Java, seperti kaedah penetap/pengambil yang paling biasa dalam pojo, seperti kaedah toString, kaedah sama, dll. Ia juga boleh membantu kami menutup strim, walaupun JDK7 sudah ada Ciri TWR dalam , tetapi pakej ini sangat berbaloi untuk dilihat. Melalui beberapa anotasi mudah, kod templat ditulis ke dalam program semasa penyusunan. Anda boleh melihat kaedah yang dihasilkan dalam tetingkap Outline menggunakan eclipse, tetapi ia bersih dalam kod sumber Untuk pemasangan, mula-mula pergi ke laman web rasmi lombok untuk memuat turun pakej jar. Muat turun sahaja pakej jar

Java adalah bahasa pengaturcaraan yang biasa digunakan yang digunakan secara meluas untuk membangunkan pelbagai jenis aplikasi. Java API ialah salah satu bahagian teras bahasa Java Ia menyediakan pembangun dengan banyak kod dan perpustakaan yang boleh digunakan semula yang boleh mempercepatkan proses pembangunan dan penggunaan aplikasi. Semasa proses pembangunan Java API, selalunya perlu menggunakan beberapa alatan dan teknik untuk memudahkan pengekodan untuk meningkatkan kebolehbacaan dan kebolehselenggaraan kod. Lombok adalah perpustakaan Java yang sangat praktikal yang boleh digunakan di Jawa

Contoh anotasi 1. @ToString: melaksanakan kaedah toString() 2. @Data: beranotasi pada kelas menyediakan kaedah mendapatkan dan menetapkan untuk semua atribut kelas Selain itu, kaedah equals, canEqual, hashCode dan toString disediakan 3. @Setter: anotasi Pada sifat; menyediakan kaedah tetapan untuk sifat. @Getter: Beranotasi pada atribut; menyediakan kaedah mendapatkan untuk atribut @Log4j: Beranotasi pada kelas menyediakan objek log log4j dengan atribut bernama log untuk kelas @NoArgsConstructor: Beranotasi pada kelas; kelas @Semua
