查看原文
其他

为什么阿里巴巴要求 POJO 中不能使用基本数据类型?

The following article is from Hollis Author Hollis

点击关注公众号,一周多次包邮送书

来源:经授权转自 Hollis(ID:hollischuang)作者:Hollis
在《阿里巴巴Java开发手册》中,对于POJO中如何选择变量的类型以及 RPC 接口中的返回值类型也有着一些规定:
这里强制要求使用包装类型,原因是什么呢?我们来看一段简单的代码

     /**

     * @author Hollis

     */

    public class BooleanMainTest {

        public static void main(String[] args) {

            Model model1 = new Model();

            System.out.println("default model : " + model1);

        }

    }

    class Model {

        /**

         * 定一个Boolean类型的success成员变量

         */

        private Boolean success;

        /**

         * 定一个boolean类型的failure成员变量

         */

        private boolean failure;

        /**

         * 覆盖toString方法,使用Java 8 的StringJoiner

         */

        @Override

        public String toString() {

            return new StringJoiner(", ", Model.class.getSimpleName() + "[", "]")

                .add("success=" + success)

                .add("failure=" + failure)

                .toString();

        }

    }

以上代码输出结果为:

    default model : Model[success=null, failure=false]

可以看到,当我们没有设置Model对象的字段的值的时候,Boolean类型的变量会设置默认值为null,而boolean类型的变量会设置默认值为false即Boolean对象的默认值是null,boolean基本数据类型的默认值是false也就是说,包装类型的默认值都是null,而基本数据类型的默认值是一个固定值,如boolean是false,byte、short、int、long是0,float是0.0f等;我们再举一个扣费的例子,我们做一个扣费系统,扣费时需要从外部的定价系统中通过 RPC 请求读取一个费率的值,我们预期该接口的返回值中会包含一个浮点型的费率字段。当我们取到这个值得时候就使用公式:金额*费率=费用 进行计算,计算结果进行划扣。如果由于计费系统异常,他可能会返回个默认值,如果这个字段是Double类型的话,该默认值为null,如果该字段是double类型的话,该默认值为0.0。如果扣费系统对于该费率返回值没做特殊处理的话,拿到null值进行计算会直接报错,阻断程序。拿到0.0可能就直接进行计算,得出接口为0后进行扣费了。这种异常情况就无法被感知。有人说,那我可以对0.0做特殊判断,如果是0一样可以阻断报错啊。但是,这时候就会产生一个问题,如果允许费率是0的场景又怎么处理呢?所以,使用基本数据类型只会让方案越来越复杂,坑越来越多。这种使用包装类型定义变量的方式,通过异常来阻断程序,进而可以被识别到这种线上问题。如果使用基本数据类型的话,系统可能不会报错,进而认为无异常。当然,以上的选择是针对一些电商、支付、金融等场景,可以牺牲暂时的可用性的场景,如果是对于某些软件系统,可以容忍数据不准,但是不能系统不可用的情况要另当别论。以上,就是要求在POJO和RPC的返回值中使用包装类型的原因。·················END·················

推荐阅读

•  燃!Python实现导弹自动追踪!•  淦,为什么 "𠮷𠮷𠮷" .length !== 3•  @Bean与@Component 同时作用同一个类,会怎么样?
•  stack vs heap:栈区分配内存快还是堆区分配内存快 ?•  isEmpty 和 isBlank 的用法区别,居然一半的人答不上来.....•  Maven Archetype 多 Module 自定义代码脚手架•  豆瓣 9.1!二刷了这本经典,YYDS•  惊了,还有一行代码实现登录认证的框架!

👇更多内容请点击👇

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存