Java反射属性的问题

前言

最近做项目,需要写一个序列化相关的框架,在javabean的属性的反射过程中,居然出现不兼容的现象。

1. 旧版本属性反射

Javabean由于书写不标准,出现属性与get、set方法不对应,模拟bean注意setNameR与getNameR方法。

public class TestBean {
    private String name;
    private Integer age;

    public String getNameR() {
        return name;
    }

    public void setNameR(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

但是非常奇怪,序列化属性什么都正常,经过源码分析,原来是通过

Introspector.getBeanInfo(TestBean.class)

这种方式反射get与set方法。

public class ReflectMain {
    public static void main(String[] args) throws IntrospectionException {
        BeanInfo beanInfo = Introspector.getBeanInfo(TestBean.class);
        Field[] fields = TestBean.class.getDeclaredFields();

        for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()){
            if ("class".equals(descriptor.getName())){
                continue;
            }
            System.out.println("writeMethod:\t" + descriptor.getWriteMethod().getName() + "\t-----\t" + "readMethod:\t" + descriptor.getReadMethod().getName());
        }

        
        System.out.println("----------------------------");
    }
}

结果如下: 

writeMethod:	setAge	-----	readMethod:	getAge
writeMethod:	setNameR	-----	readMethod:	getNameR
----------------------------

2. 标准的反射

由于写的新框架使用java标准的set与get方法

public class ReflectMain {
    public static void main(String[] args) throws IntrospectionException {
        Field[] fields = TestBean.class.getDeclaredFields();

        for (Field field : fields){
            System.out.println("field is:\t" + field.getName());
        }

        System.out.println("----------------------------");
    }
}

使用属性名称,判断是否boolean值,拼接set或者is方法(这是ali不推荐boolean使用is开头命名的原因,序列化方式可能会导致is丢失)

结果如下:

field is:	name
field is:	age
----------------------------

3.原理分析

反射获取set和get方法的方式不一样,标准的javabean是属性与set、get方法名称一致

使用fastjson测试

public class FastJsonTest {
    public static void main(String[] args) {
        TestBean testBean = new TestBean();
        testBean.setAge(11);
        testBean.setNameR("Tom");
        String json = JSON.toJSONString(testBean);
        System.out.println(json);
    }
}

结果如下:

{"age":11,"nameR":"Tom"}

属性,变成nameR了。

总结

javabean的标准非常重要,属性与set、get方法对应对于框架的开发非常重要

如果生产上出现这个问题,解决方法:

由于序列化后的json是nameR,那么可以将javabean的属性改为nameR,这样就实现了标准的javabean,序列化正常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值