0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

新来个技术总监:谁在用isXxx形式定义布尔类型年后不用来了

jf_ro2CN3Fa 来源:Hollis 2023-06-11 16:00 次阅读


在日常开发中,我们会经常要在类中定义布尔类型的变量,比如在给外部系统提供一个RPC接口的时候,我们一般会定义一个字段表示本次请求是否成功的。

关于这个”本次请求是否成功”的字段的定义,我见过很多不同的开发者,定义的方式都不同,尤其是在属性的命名上,有人用 success,有人用 isSuccess 表示。

从语义上面来讲,两种命名方式都可以讲的通,并且也都没有歧义。那么还有什么原则可以参考来让我们做选择呢。

根据JavaBeans Specification规定,如果是普通的参数propertyName,要以以下方式定义其setter/getter:

publicget();

publicvoidset(a);

但是,布尔类型的变量propertyName则是单独定义的:

publicbooleanis();

publicvoidset(booleanm);

success方法的 getter 应该是isSuccess/getSuccess,而isSuccess的getter 应该是isIsSuccess/getIsSuccess。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

但是很多人,在使用isSuccess作为属性名的时候,还是会采用isSuccess/getSuccess作为 getter 方法名,尤其是现在的很多 IDE 在默认生成 getter 的时候也是会生成isSuccess。

在一般情况下,其实是没有影响的。但是有一种特殊情况就会有问题,那就是发生序列化的时候可能会导致参数转换异常。

我们先来定义一个 JavaBean:

classModelimplementsSerializable{


privatestaticfinallongserialVersionUID=1836697963736227954L;

privatebooleanisSuccess;

publicbooleanisSuccess(){

returnisSuccess;

}

publicvoidsetSuccess(booleansuccess){

isSuccess=success;

}

publicStringgetHollis(){

return"yudaoyuanma";

}

}

在这个 JavaBean 中,有一个成员变量isSuccess,三个方法,分别是IDE帮我们自动生成的isSuccess和setSuccess,另外一个是作者自己增加的一个符合getter命名规范的方法。

我们分别使用不同的 JSON 序列化工具来对这个类的对象进行序列化和反序列化:

publicclassBooleanMainTest{

publicstaticvoidmain(String[]args)throwsIOException{

//定一个Model类型

Modelmodel=newModel();

model.setSuccess(true);



//使用fastjson(1.2.16)序列化model成字符串并输出

System.out.println("SerializableResultWithfastjson:"+JSON.toJSONString(model));



//使用Gson(2.8.5)序列化model成字符串并输出

Gsongson=newGson();

System.out.println("SerializableResultWithGson:"+gson.toJson(model));



//使用jackson(2.9.7)序列化model成字符串并输出

ObjectMapperom=newObjectMapper();

System.out.println("SerializableResultWithjackson:"+om.writeValueAsString(model));

}

}

以上代码输出结果:

SerializableResultWithfastjson:{"yudao":"yudaoyuanma","success":true}

SerializableResultWithGson:{"isSuccess":true}

SerializableResultWithjackson:{"success":true,"yudao":"yudaoyuanma"}

在fastjson和jackson的结果中,原来类中的isSuccess字段被序列化成success,并且其中还包含yudao值。而Gson中只有isSuccess字段。

我们可以得出结论:fastjson和jackson在把对象序列化成json字符串的时候,是通过反射遍历出该类中的所有getter方法,得到getHollis和isSuccess,然后根据JavaBeans规则,他会认为这是两个属性yudao和success的值。直接序列化成json:

{“yudao”:”yudaoyuanma”,”success”:true}

但是Gson并不是这么做的,他是通过反射遍历该类中的所有属性,并把其值序列化成json:

{“isSuccess”:true}

可以看到,由于不同的序列化工具,在进行序列化的时候使用到的策略是不一样的 ,所以,对于同一个类的同一个对象的序列化结果可能是不同的。那么,如果我们把一个对象使用fastjson进行序列化,再使用Gson反序列化会发生什么呢?

publicclassBooleanMainTest{

publicstaticvoidmain(String[]args)throwsIOException{

Modelmodel=newModel();

model.setSuccess(true);

Gsongson=newGson();

System.out.println(gson.fromJson(JSON.toJSONString(model),Model.class));

}

}

以上代码,输出结果:

Model[isSuccess=false]

这和我们预期的结果完全相反,原因是因为JSON框架通过扫描所有的getter后发现有一个isSuccess方法,然后根据JavaBeans的规范,解析出变量名为success,把model对象序列化城字符串后内容为{"success":true}。

根据{"success":true}这个json串,Gson框架在通过解析后,通过反射寻找Model类中的success属性,但是Model类中只有isSuccess属性,所以,最终反序列化后的Model类的对象中,isSuccess则会使用默认值false。

但是,一旦以上代码发生在生产环境,这绝对是一个致命的问题。

所以,作为开发者,我们应该想办法尽量避免这种问题的发生。

所以,建议大家使用success而不是 isSuccess 这种形式。 这样,该类里面的成员变量时success,getter方法是isSuccess,这是完全符合JavaBeans规范的。无论哪种序列化框架,执行结果都一样。就从源头避免了这个问题。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    8497

    浏览量

    150834
  • 参数
    +关注

    关注

    11

    文章

    1785

    浏览量

    32086
  • RPC
    RPC
    +关注

    关注

    0

    文章

    111

    浏览量

    11512

原文标题:新来个技术总监:谁在用isXxx形式定义布尔类型年后不用来了

文章出处:【微信号:芋道源码,微信公众号:芋道源码】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    鸿蒙原生应用元服务开发-仓颉基础数据类型布尔类型

    布尔类型使用Bool 表示,用来表示逻辑中的真和假。 布尔类型字面量 布尔
    发表于 09-09 09:57

    技术总监(硬件系统)-北京

    技术总监(硬件系统)-北京任职要求:1.通信、电子计算机相关专业硕士以上学历;2.年龄30-40之间,有在集成电路设计公司或其他电子公司做过技术总监;3.可以偏硬件系统设计,主要是基于
    发表于 03-27 10:47

    谁在大的公司搞技术求推荐

    谁在大的公司搞技术求推荐?只求学习技术,工资可以不要给推荐人
    发表于 04-06 15:53

    w7500P,谁在用啊,串口转以太的需要什么程序,要怎么烧进去啊??

    ,,望大神指路,,w7500P,谁在用啊,串口转以太的需要什么程序,要怎么烧进去啊??
    发表于 07-17 21:42

    模拟IC设计总监/技术总监-广东

    技术总监/模拟IC设计总监-广州 珠海岗位职责:1、负责制定技术路线和产品路线;2、指导研发团队新产品定义、立项、设计、验证;3、指导研发团
    发表于 09-01 16:38

    如何在前面板把布尔设置为透明,不用定义控件改变布尔的外形

    `如图,四个布尔控件不是自定义控件,怎么只凭图片改变外形?“会计小贴士-real” “说明”怎么设置透明 请各位帮忙@amywu1981 @ShuiMoLise @wuyaning222331
    发表于 08-31 12:04

    高压线性有什么型号比较好的,都有谁在用啊?推荐一下

    高压线性有什么型号比较好的,都有谁在用啊?推荐一下
    发表于 01-16 11:08

    还有谁在用MCIMX6Q5EY10AD

    我们项目升级成IMX8,有5包 MCIMX6Q5EY10AD 想转让,请问有谁在用啊,谢谢!张工 壹叁柒 2421 2401
    发表于 02-16 20:05

    布尔代数,布尔代数是什么意思

    布尔代数,布尔代数是什么意思 布尔代数最初是作为对逻辑思维法则的研究出现的。英国哲学家George Boole于1847年的论文“逻辑之数学分析”及“思维法则之研究”中引
    发表于 03-08 11:04 8356次阅读

    硬件类型定义

    “hw_types.h” 里,定义布尔类型 tBoolean,以及与其相关的常量 true 和 false,以方便操作。
    发表于 01-13 16:32 7次下载

    布尔代数定律的描述

    布尔代数是我们用来分析数字门和电路的数学。我们可以使用这些“布尔定律”来减少和简化复杂的布尔表达式,以减少所需的逻辑门数。因此,布尔代数是一
    的头像 发表于 06-22 09:36 7225次阅读
    <b class='flag-5'>布尔</b>代数定律的描述

    c++ 之布尔类型和引用的学习总结

    在c语言里面我们知道是没有布尔数据类型的,而在C++中添加了布尔数据类型(bool),它的取值是:true或者false(也就是1或者0),在内存大小上它占用一个字节大小。
    的头像 发表于 12-24 18:03 569次阅读

    基于布尔函数导数的布尔置换构造

    布尔函数导数的性质在密码构造中起着重要的作用。文中利用布尔函数导数的性质,构造了一个新的平衡布尔函数然后基于平衡布尔函数与布尔置换的关系,构
    发表于 06-17 10:58 15次下载

    python布尔值是什么

    python布尔值 1. 什么是布尔值 但在Python语言中,布尔类型只有两个值 True :表示真值 False :表示假值 请注意,首字母要大写,不能是其它花式变型。 所有的计算
    的头像 发表于 02-21 16:10 6868次阅读

    定义数据类型

    在运算之前我们必须首先定义出数据类型,定义出脚本支持的数据类型,这是运算的基础。 这一小节我们将定义出数据
    的头像 发表于 03-03 10:10 909次阅读