问题
lombok的@Data注解无法给final修饰的变量构建get方法
想看解决方法直接跳到最后
背景:
需要写一个工具类,将json数据转化为xml格式。json数据是从数据库中查询得到,生成xml报文采用Element类添加报文节点来组装xml报文。
思路
数据库中查询得到的数据放在实体类中,使用@Data注解生成getset以及构造方法。工具类采用反射来获得实体类中所有数据,然后将取出来的值构建xml报文
上代码:
实体类:
import lombok.Data;
@Data
public class Student {
public static final Long Version = 1L;
private Integer id;
private String name;
private String className;
}
测试类
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test {
public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Student student = new Student();
student.setClassName("一班");
student.setName("张三");
student.setId(1);
addpojo(student);
}
public static <T> void addpojo(Object pojo) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//获得所有字段名
Field[] fields = pojo.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
//获得字段名称
String strFieldName = fields[i].getName();
//首字母大写方便构造getset方法
strFieldName = strFieldName.substring(0, 1).toUpperCase() + strFieldName.substring(1);
//构建get方法
Method m = pojo.getClass().getMethod("get" + strFieldName);
//执行get方法
Object invoke = m.invoke(pojo);
}
}
}
问题:
在执行get方法的时候,会报错
java.lang.NoSuchMethodException: demo.pojo.Student.getVersion()
找不到getVersion()方法
排查问题
查看编译好的target文件夹下实体类的class文件,发现编译完成之后,并没有生成getVersion()方法,
public class Student {
public static final Long Version = 1L;
private Integer id;
private String name;
private String className;
public Student() {
}
public Integer getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getClassName() {
return this.className;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setClassName(String className) {
this.className = className;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Student)) {
return false;
} else {
Student other = (Student)o;
if (!other.canEqual(this)) {
return false;
} else {
label47: {
Object this$id = this.getId();
Object other$id = other.getId();
if (this$id == null) {
if (other$id == null) {
break label47;
}
} else if (this$id.equals(other$id)) {
break label47;
}
return false;
}
Object this$name = this.getName();
Object other$name = other.getName();
if (this$name == null) {
if (other$name != null) {
return false;
}
} else if (!this$name.equals(other$name)) {
return false;
}
Object this$className = this.getClassName();
Object other$className = other.getClassName();
if (this$className == null) {
if (other$className != null) {
return false;
}
} else if (!this$className.equals(other$className)) {
return false;
}
return true;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Student;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $id = this.getId();
int result = result * 59 + ($id == null ? 43 : $id.hashCode());
Object $name = this.getName();
result = result * 59 + ($name == null ? 43 : $name.hashCode());
Object $className = this.getClassName();
result = result * 59 + ($className == null ? 43 : $className.hashCode());
return result;
}
public String toString() {
return "Student(id=" + this.getId() + ", name=" + this.getName() + ", className=" + this.getClassName() + ")";
}
}
解决方法
方案1:
在工具类中增加一个判断,如果是final修饰的,则跳过本次循环。
通过fields[i].getModifiers()来获得字段修饰信息
通过Modifier.isfinal(xxx)来判断修饰信息是否为final
//获得所有字段名
Field[] fields = pojo.getClass().getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
//判断是否是fianl修饰,如果是,则continue,
if (Modifier.isFinal(fields[i].getModifiers())) {
continue;
}
方案2:
在实体类中增加get方法
public static Long getVersion() {
return Version;
}