在Java中,return null 是否安全, 为什么?
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,如果会返回空指针,那应该说明原因和语义,让调用者有章可依。
在Java中,return null 是否安全, 为什么?的更多相关文章
- Java中有关Null的9件事
对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常 (NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我 ...
- 转!!Java中关于Null的9个解释(Java Null详解)
对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认 ...
- JAVA中String = null 与 String = "" 的区别
JAVA中String = null 与 String = ""的区别 笔者今天在Debug的时候发现的NPE(NullPointerException),辛辛苦苦地调试了半天,终 ...
- 关于Java中的Null
什么是Java中的Null? null在Java中是一个非常重要的概念,它最初是为了表示缺少某些东西,例如缺少用户.资源或任何东西而发明出来的.但是这也为Java程序员带来了很多麻烦,比如最常见的空指 ...
- 经典的java中return和finally问题!
经典的java中return和finally问题! 标签: 杂谈 分类: java学习 前一段时间 参加公司的笔试问了这个问题,回来一查才知道当时自己做错了,百思不得其解,上网查到下面的程序,但是运行 ...
- Java中的Null是什么?
对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认 ...
- Java中有关Null的9件事(转)
对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认 ...
- java中,null值可以被强制转换为任何类型
java中,null值可以被强制转换为任何类型
- 关于 Java 中的 Null
什么是Java中的Null? null在Java中是一个非常重要的概念,它最初是为了表示缺少某些东西,例如缺少用户.资源或任何东西而发明出来的.但是这也为Java程序员带来了很多麻烦,比如最常见的空指 ...
- java中的null类型---有关null的9件事
摘自 https://blog.csdn.net/qq_25077777/article/details/80174763 今天听到一个问题,java中的null类型,null竟然是一种类型 java ...
随机推荐
- ORACLE-016:ora-01720 授权选项对于'xxxx'不存在
报错的情形例如以下. A用户:视图V_A B用户:视图V_B,而且用到了V_A C用户:须要用V_B, 授权过程, A用户下: grant select on V_A to B B用户下: grant ...
- HH生病了(hpu1136)
HH生病了 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 324 Solved: 90 [Submit][Status][Web Board] De ...
- Linux监控(OS,MySQL,Tomcat,Apache)
关于逐步脱离开发岗位的意见,老大已经批准了,接下来我的主要工作就是"运维+数据库管理".感谢杰民兄和小马哥能接受我的骚扰.接下来还会去骚扰他们,同一时候也会去骚扰董大爷,小刚总,心 ...
- Reuse Is About People and Education, Not Just Architecture
 Reuse Is About People and Education, Not Just Architecture Jeremy Meyer you MigHT AdopT THE AppRoA ...
- codeforce 571 B Minimization
题意:给出一个序列,经过合适的排序后.使得最小. 做法:将a升序排序后,dp[i][j]:选择i个数量为n/k的集合,选择j个数量为n/k+1的集合的最小值. 举个样例, a={1,2,3,4,5,6 ...
- json和XML
发请求(url) 1.client ---------------->服务端 发送数据(Json/xml) < - ...
- 利用css去除input按钮上的文字的几种方法
相信很多时候input上的文字困扰着web前端开发者,必须要通过修改html代码中的value值才能清空按钮上的文字,但很多人不愿意去动html代码,一方面麻烦,另外主要的原因还在于保留文字对seo有 ...
- centos 6.7下安装rabbitmq 3.6.6过程
准备,请确保有root权限或者sudo权限,不然不用继续看下去了. 1.erland的安装 首先测试一下是否已经安装了erlang,命令 rpm -qa | grep erlang 若没有安装,则 y ...
- android学习笔记五。1、Service深入学习
一.Service,服务是没有界面而在后台长期运行的程序,可以看做是后台的Activity. 1.在Android中按返回键退出一个应用并不会(内存充足时)直接销毁一个进程,所以其中的子线程也可以在后 ...
- private SortedDictionary<string, object> Dic_values = new SortedDictionary<string, object>();
private SortedDictionary<string, object> Dic_values = new SortedDictionary<string, object&g ...