在Java中,return null 是否安全, 为什么?

2023-05-16

Java代码中return value 为null 是不是在任何情况下都可以,为什么不会throw NullPointerException?


Java语言层面:null值自身是不会引起任何问题的。它安安静静的待在某个地方(局部变量、成员字段、静态字段)不会有任何问题;它从一个地方被搬运到另一个地方也不会有任何问题(变量赋值、返回值等)。唯一会因为null值而引起NullPointerException的动作是“解引用”(dereference)——也就是通过这个引用要对其引用的对象做操作。俗话说就是所有隐含“obj.xxx”的操作中,obj为null值的情况。
在Java里,下述操作隐含对引用的解引用:


 读字段(字节码 getfield):x.y,当x为null时抛NPE;
    写字段(字节码 putfield):x.y = z,当x为null时抛NPE。注意:z的值是什么没关系;
    读数组长度(字节码 arraylength):a.length,当a为null时抛NPE;
    读数组元素(字节码 <x>aload,<x>为类型前缀):a[i],当a为null时抛NPE;
    写数组元素(字节码 <x>astore,<x>为类型前缀):a[i] = x,当a为null时抛NPE。注意:x的值时什么没关系;
    调用成员方法(字节码 invokevirtual、invokeinterface、invokespecial):obj.foo(x, y, z),当obj为null时抛NPE。注意:参数的值是什么没关系;
    增强for循环(也叫foreach循环):
        对数组时(实际隐含a.length操作):for (E e : a) { ... } , 当a为null时抛NPE;
        对Iterable时(实际隐含对Iterable.iterator()的调用):for (E e : es) { ... } ,当es为null时抛NPE;
    自动拆箱(实际隐含 <XXX>.<xxx>Value() 的调用,<XXX>为包装类型名,<xxx>为对应的原始类型名): (int) integerObj,当integerObj为null时抛NPE;
    对String做switch(实际隐含的操作包含对String.hashCode()的调用):switch (s) { case "abc": ... } ,当s为null时抛NPE;
    创建内部类对象实例(字节码 new,但这里特指创建内部类实例的情况):outer.new Inner(x, y, z),当outer为null时抛NPE;
    抛异常(字节码 athrow):throw obj,当obj(throw表达式的参数)为null时抛NPE;
    用synchronized关键字给对象加锁(字节码 monitorenter / monitorexit):synchronized (obj) { ... },当obj为null时抛NPE。


Java语言里所有其它语法结构都不会因为null值而隐含抛NPE的语义。当然,用户可以在自己需要的地方显式检查null值然后自己抛出NPE,就像:


java.util.Objects.requireNonNull(Object)

    /**
     * Checks that the specified object reference is not {@code null}. This
     * method is designed primarily for doing parameter validation in methods
     * and constructors, as demonstrated below:
     * <blockquote><pre>
     * public Foo(Bar bar) {
     *     this.bar = Objects.requireNonNull(bar);
     * }
     * </pre></blockquote>
     *
     * @param obj the object reference to check for nullity
     * @param <T> the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     */
    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

自己主动throw new NullPointerException()这种情况JVM管不着,用户代码主动指定的,用户想怎么搞就怎么搞。


趣味题:在Java语言里,只使用Java语言及标准库的功能而不依赖第三方库,检查一个引用obj是否为null并在null时抛NPE的代码是什么?
答案:obj.getClass()。这是因为getClass()是java.lang.Object类上的方法,因而无论什么引用类型都可以使用。这在Java源码层面和在Java字节码层面上都是最短的。
当然这是个很邪恶的歪招,然而在OpenJDK的标准库内部实现中并不少见。大家…还是用Objects.requireNonNull()就好了.


return null主要多了一个麻烦,凡是调用它的地方,都要想一想,是不是要判断if (xxx == null),这样代码不够优雅。


语言层面上讲,返回null没有任何问题,大家都赞同。
工程实践中,返回null是否就是个不好的习惯?我倒不这么认为。我的观点是,所有的方法调用,无论是自己工程的内部类方法还是第三方包中的方法,除非对方在Java Doc中显式的说明了不会返回空,其它情况都应该怀疑有返回空指针的可能性。多一个判断并没有什么不好,还能大大增加代码的健壮性。在另一方面,方法的编写者也应该仔细的维护Java Doc,如果会返回空指针,那应该说明原因和语义,让调用者有章可依。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Java中,return null 是否安全, 为什么? 的相关文章

随机推荐

  • C++ 值传递、指针传递、引用传递详解

    具体内容源自 xff1a http www cnblogs com yanlingyin archive 2011 12 07 2278961 html 以下是简介 xff1a 值传递 xff1a 形参是实参的拷贝 xff0c 改变形参的值
  • MATLAB: 读取同一目录下的所有文件名并按时间排序

    用MATLAB测试图像处理算法的过程中 通常需要读入一个目录下的多张测试图片 可以根据文件命名规则来读入某个特定目录下的所有文件 但是相对比较麻烦 通过利用MATLAB自带的dir 可以先读入所有的文件名字 知道文件数量 而且不用知道文件的
  • 相机模型(Camera Model)

    Perspective Camera Model Perspective Camera Model 或 Pinhole Camera Model都是简单但是应用广泛的模型 xff0c 描述了将物体从3D世界坐标系转换 xff08 World
  • Solid Compression

    定义 Solid Compression是一种多文件的数据压缩方式 xff0c 其中所有未被压缩的文件是一个整体 xff0c 视为一个独立的data block 这样的文件称为solid archive 7z RAR压缩格式和tar bas
  • 区分AR、VR、MR、CR

    终极扫盲贴 xff1a VR AR MR CR到底如何区分 xff1f
  • (2016/02/19)多传感器数据融合算法---9轴惯性传感器

    2016年2月18日 传感器的原理 加速度计 xff1a 加速度计 我们可以把它想作一个圆球在一个方盒子中 假定这个盒子不在重力场中或者其他任何会影响球的位置的场中 xff0c 球处于盒子的正中央 你可以想象盒子在外太空中 xff0c 或远
  • 【tx2】——NVIDIA TX2--3--NVIDIA Jetson TX2 查看系统版本参数状态及重要指令

    NVIDIA Jetson TX2 查看系统参数状态 当前博主的TX2更新的版本为 xff1a Jetpack 3 3 cuda 9 0 252 cudnn7 0 opencv3 3 1 TensorRT4 0 2 系统内核 xff1a t
  • 训练深度学习模型时电脑自动重启

    文章目录 问题可能原因解决方案 问题 前面用自己的台式机利用GPU训练模型的时候 xff0c 电脑老是自动重启 xff0c 当时试了各种方法 xff0c 找了各种原因 电脑配置 电脑买的是二手的 xff0c xff08 强烈建议买新的 xf
  • 华为机试题[2017.8.23]

    题目 xff1a 给定一个正整数 xff0c 给出消除重复数字以后最大的整数 输入描述 xff1a 正整数 xff0c 注意考虑长整数 输出描述 xff1a 消除重复数字以后的最大整数 下面的好像有问题 xff0c 当输入是4325432时
  • Kubernetes(k8s)中dashboard的汉化

    1 访问服务器的http 192 168 110 133 8080 ui地址 xff0c 如下所示 xff1a 使用dashboard版本registry cn hangzhou aliyuncs com google containers
  • docker + Rancher + guacamole 容器环境搭建并配置vnc连接

    Rancher 43 guacamole 容器环境搭建 准备环境 xff1a docker ce 17 01 43 43 centos7 x 43 guacamole 最新版0 9 14 43 Rancher 搭建完成效果 xff1a 1
  • C语言习题(1)——字符串拷贝,去空格,奇偶抽取字符串

    1 字符串拷贝 作者 xff1a 一叶扁舟 作用 xff1a 字符串的拷贝 时间 xff1a 18 25 2017 5 1 include lt stdio h gt include lt string h gt include lt st
  • 基于安卓平台的滤镜功能相机

    1 1需求背景 爱美之心 xff0c 人皆有之 我们拍照是为了留住一个美好的瞬间 Android自带的相机拍照效果满足不了人们的爱美心理 xff0c 而且比较单一 xff1b 因此为了解决这个问题我们研 发 滤镜功能相机 滤镜功能相机主要基
  • 威廉·巴特勒·叶芝:“我们是最后的浪漫主义者”

    喜欢叶芝是一件很文艺的事情 叶芝的诗滋润了无数少男少女的情怀 在叶芝被茅德 冈 嫌弃的这一生中 我们不知道他是否曾经后悔 我感动了全世界 却感动不了你 但至少 他的诗 感动了后世无数人 题记 多少人曾爱你青春欢畅的时辰 爱慕你的美丽 假意或
  • Javassist即时编译技术,热修复核心与原理

    Java 字节码以二进制的形式存储在 class 文件中 xff0c 每一个 class 文件包含一个Java类或接口 Javaassist 框架就是一个用来处理 Java 字节码的类库 它可以在一个已经编译好的类中添加新的方法 xff0c
  • ubuntu系统编译安装

    Ubuntu程序安装是个很好理解的 xff0c 这里我发表一下个人理解 xff0c 下面就这就来讲术Ubuntu编译安装 Ubuntu编译程序新手指导Ubuntu 团队对它的使用者公开的承诺 Ubuntu 永远免费 并且对于 34 企业版本
  • Android Launcher浅析(一)

    Launcher桌面的一大功能就是支持左右滑动 xff0c 这样的功能在现在的应用中使用非常广泛 xff0c 并且有很多实现的方式 xff0c 可以通过使用Fragment来实现也可以通过自定义的控件来实现 Launcher采用了后者 xf
  • Android OTA升级

    1 xff0c Build otapackage后system img没有打包进去 xff1f Ota包里面缺失system img xff0c 原因是客户修改了prop里面的 ro product device value值 尝试以下两种
  • Android Launcher浅析(三)

    Launcher是系统启动后第一个启动的程序 是其它应用程序的入口 也就是我们的手机程序的桌面程序 一 Launcher的定义及构成 xff1a lt 1 gt 通过查看官方提供的Launcher源码可以知道其实Launcher也是一个Ac
  • 在Java中,return null 是否安全, 为什么?

    Java代码中return value 为null 是不是在任何情况下都可以 xff0c 为什么不会throw NullPointerException Java语言层面 xff1a null值自身是不会引起任何问题的 它安安静静的待在某个