【solvebug】Java反射报错java.beans.IntrospectionException: Method not found,lombok的@Accessors注解
问题描述
Java 反射报错 java.beans.IntrospectionException: Method not found:setXXXX
问题分析及解决
1、getter/setter 方法命名不规范,就是setXxx, setxxx这样的大小写;
2、实体类方法返回值问题
使用 PropertyDescriptor descriptor = new PropertyDescriptor(fieldName, classz)时,要求 setter 返回值为 void,getter 返回值为属性类型,如下的 getter 方法返回的类型就不对,会报 Method not found 错误
private Date startDate;
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setStartDate</span><span class="hljs-params">(Date startDate)</span> {
<span class="hljs-built_in">this</span>.startDate = startDate;
}
<span class="hljs-comment">//将方法返回类型改成Date就解决了</span>
<span class="hljs-keyword">public</span> String <span class="hljs-title function_">getStartDate</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">return</span> DateUtil.formatDate(startDate);
}
3、实体类使用了lombok 中的 @Accessors(chain = true) 注解
该注解使得对象的 setter 方法返回对象本身,以便链式使用
new PropertyDescriptor(propertyName, clazz); 要求 setter 返回值为 void
解决:去掉 @Accessors(chain = true) 注解即可。或者在根据业务需求为需要反射的属性添加相应的 getter/setter 方法。
Demo 反编译验证
使用 lombok.Data
/**
* <p>@Author: healker</p>
* <p>@datetime: 2020/8/26 11:36</p>
* <p>@description: </p>
*/
@Data
public class EntityDemo {
private String testField;
private List<EntityDemo> entityDemoList;
}
编译成 class,再反编译后
使用 lombok.Data,并添加 @Accessors(chain = true) 注解
/**
* <p>@Author: healker</p>
* <p>@datetime: 2020/8/26 11:36</p>
* <p>@description: </p>
*/
@Data
@Accessors(chain = true)
public class EntityDemo {
private String testField;
private List<EntityDemo> entityDemoList;
}
编译成 class,再反编译后 testField,entityDemoList 的 setter 方法都是返回实体本身(用以链式调用)。
使用 lombok.Data,并添加 @Accessors(chain = true) 注解, 手写 testField 字段的 getter/setter 方法
/**
* <p>@Author: healker</p>
* <p>@datetime: 2020/8/26 11:36</p>
* <p>@description: </p>
*/
@Data
@Accessors(chain = true)
public class EntityDemo {
private String testField;
private List<EntityDemo> entityDemoList;
<span class="hljs-keyword">public</span> String <span class="hljs-title function_">getTestField</span><span class="hljs-params">()</span> {
<span class="hljs-keyword">return</span> testField;
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">setTestField</span><span class="hljs-params">(String testField)</span> {
<span class="hljs-built_in">this</span>.testField = testField;
}
}
编译成 class,再反编译后 testField 的 setter 方法返回 void,entityDemoList 的 setter 方法返回实体本身