【老生常谈】详细了解java中的null

执笔记忆的空白
博客专家认证
2015-09-10 02:23:24
加精
相信大家对于NullPointException 这个让人又爱又恨的不陌生吧..对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰 。今天我们就来谈谈ta,了解ta ,本文有点长,请耐心看下去,对各位肯定是有帮助的

1、null的起源
null是Java中的关键字,像public、static、final。它是大小写敏感的,你不能将null写成Null或NULL,编译器将不能识别它们然后报错
Object obj = NULL; // Not Ok
Object obj1 = null //Ok


2、就像每种原始类型都有默认值一样,如int默认值为0,boolean的默认值为false,null是任何引用类型的默认值,不严格的说是所有object类型的默认值。Java中的任何引用变量都将null作为默认值。这对所有变量都是适用的,如成员变量、局部变量、实例变量、静态变量(但当你使用一个没有初始化的局部变量,编译器会警告你),如下代码所示:
private static Object myObj;
public static void main(String args[]){
System.out.println("What is value of myObjc : " + myObj);
}
1
What is value of myObjc : null


3、null既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将null转化成任何类型,来看下面的代码:
String str = null; // null can be assigned to String
Integer itr = null; // you can assign null to Integer also
Double dbl = null; // null can also be assigned to Double

String myStr = (String) null; // null can be type cast to String
Integer myItr = (Integer) null; // it can also be type casted to Integer
Double myDbl = (Double) null; // yes it's possible, no error

你可以看到在编译和运行时期,将null强制转换成任何引用类型都是可行的,在运行时期都不会抛出空指针异常。

4、null可以赋值给引用变量,你不能将null赋给基本类型变量,例如int、double、float、boolean。如果你那样做了,编译器将会报错,如下所示:
int i = null; // type mismatch : cannot convert from null to int
short s = null; // type mismatch : cannot convert from null to short
byte b = null: // type mismatch : cannot convert from null to byte
double d = null; //type mismatch : cannot convert from null to double

Integer itr = null; // this is ok
int j = itr; // 这样转没问题,但是在运行时,会有空指针异常

正如你看到的那样,当你直接将null赋值给基本类型,会出现编译错误。但是如果将null赋值给包装类object,然后将object赋给各自的基本类型,编译器不会报,但是你将会在运行时期遇到空指针异常。这是Java中的自动拆箱导致的

5、如果使用了带有null值的引用类型变量,instanceof操作将会返回false
Integer iAmNull = null;
if(iAmNull instanceof Integer){
System.out.println("iAmNull is instance of Integer");

}else{
System.out.println("iAmNull is NOT an instance of Integer");
}

输出:
iAmNull is NOT an instance of Integer

这是instanceof操作一个很重要的特性,使得对类型强制转换检查很有用

6、你可以将null传递给方法使用,这时方法可以接收任何引用类型,例如public void print(Object obj)可以这样调用print(null)。从编译角度来看这是可以的,但结果完全取决于方法。Null安全的方法,如在这个例子中的print方法,不会抛出空指针异常,只是优雅的退出。如果业务逻辑允许的话,推荐使用null安全的方法。

7、你可以使用==或者!=操作来比较null值,但是不能使用其他算法或者逻辑操作,例如小于或者大于。跟SQL不一样,在Java中null==null将返回true,如下所示:
public class Test {
public static void main(String args[]) throws InterruptedException {
String abc = null;
if(abc == null){
System.out.println("null == null is true in Java");
}
if(abc != null){
System.out.println("null != null is false in Java");
}
}
}

输出:null == null is true in Java
8、任何一个对象或者一个引用变量为null的时候,这时如果调用其属性或方法,就会出现NullPointException..
例如:
public class Test1 {
public static void main(String[] args) throws ParseException {
String s = null; //初始化字符串为null
System.out.println(s.equals("null")); //这里调用为null的字符串的equals方法,会报NullPointException
String str = new String();
System.out.println(str.equals("null")); //这个调用就没问题,因为new 了一个对象,str不是null,只是对象里面是空壳而已
}
}

第8点在程序中是出现最多的,可能是我们自己定义了一个对象,或者从外部引用了一个对象,却没有发现这个对象是null,然后去调用其属性或者方法的时候,就会出现空指针了,这点切记切记

9、null的其他用途和注意事项
(1)释放内存,让一个非null的引用类型变量指向null。这样这个对象就不再被任何对象应用了。等待JVM垃圾回收机制去回收。
(2)List:允许重复元素,可以加入任意多个null。(这里添加的对象如果为空,拿出来用属性的时候就要注意非空验证了)
Set:不允许重复元素,最多可以加入一个null。
Map:Map的key最多可以加入一个null,value字段没有限制。



以上文章为归纳总结,也有引用的地方,原文:Java中有关Null的9件事

...全文
6122 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
钟渊 2016-11-02
  • 打赏
  • 举报
回复
感谢楼主的分享!
_小确幸 2016-09-04
  • 打赏
  • 举报
回复
获益匪浅!
tiffany2016 2016-08-04
  • 打赏
  • 举报
回复
感觉确实可以加点jvm部分的。。 不过码字还是很辛苦的。。哈哈~ 给楼主点赞~
yanqwe123 2016-07-30
  • 打赏
  • 举报
回复
JC_WorkSpace 2016-01-22
  • 打赏
  • 举报
回复
感谢分享!赞一个!!!
dai_mo 2016-01-15
  • 打赏
  • 举报
回复
学习了
dpj2008 2015-12-30
  • 打赏
  • 举报
回复
赞一个,谢谢楼主分享
云中雁012345 2015-12-01
  • 打赏
  • 举报
回复
感谢楼主无私分享。
hxybt01 2015-11-26
  • 打赏
  • 举报
回复
感谢楼主,有所收获!
阿飞不会飞丶 2015-09-25
  • 打赏
  • 举报
回复
有道理
defi 2015-09-14
  • 打赏
  • 举报
回复
写得挺好 有收获!
bestlinks0 2015-09-14
  • 打赏
  • 举报
回复
恩,写的很好,很有收获,对于null和空指针的出现一直挺迷茫的
  • 打赏
  • 举报
回复
引用 25 楼 WiseWolf_Life 的回复:
不明白的是,为什么第一题输出String?
null在向上转型的时候,如果有定义引用类型,则优先定义的引用类型,其次才是Object, 你可以把fun(String o) 改成 fun(Integer o), 输出结果依然会是优先Integer
  • 打赏
  • 举报
回复
引用 24 楼 WiseWolf_Life 的回复:
2.map的key和value可以同时为null吗?
可以,但是key只能出现一次
tejiu26 2015-09-13
  • 打赏
  • 举报
回复
WiseWolf_Life 2015-09-12
  • 打赏
  • 举报
回复
//没登录,提交的内容居然不保存,我日... 昨天笔试完美的时候,碰到两道关于null的题。 1.
public static void main(String[] args) {
		new Ss().fun(null);
	}
	public void fun(Object o){
		System.out.println("Object");
	}
	public void fun(String o){
		System.out.println("String");
	}
输出应该是什么? 2.map的key和value可以同时为null吗?
WiseWolf_Life 2015-09-12
  • 打赏
  • 举报
回复
引用 24 楼 WiseWolf_Life 的回复:
//没登录,提交的内容居然不保存,我日... 昨天笔试完美的时候,碰到两道关于null的题。 1.
public static void main(String[] args) {
		new Ss().fun(null);
	}
	public void fun(Object o){
		System.out.println("Object");
	}
	public void fun(String o){
		System.out.println("String");
	}
输出应该是什么? 2.map的key和value可以同时为null吗?
不明白的是,为什么第一题输出String?
  • 打赏
  • 举报
回复
引用 21 楼 hadoop333 的回复:
版主 你的标题错了啊 应该是java中的null 而不是你写的java中的Null 改一下吧
恩,谢谢提醒,已经更改
-阿克蒙德- 2015-09-11
  • 打赏
  • 举报
回复
我竟然无言以对
hadoop333 2015-09-11
  • 打赏
  • 举报
回复
引用 18 楼 shijing266 的回复:
看看 [quote=引用 16 楼 zhuangqingch 的回复:] 别外,如果可以的话,可以加上null的一点扩展知识,如null在JVM中的表示形式,加上这个可以解答别人在null的字节占用上的疑惑:根据JVM规范jvms-2.4点中的声明:“The Java Virtual Machine specification does not mandate a concrete value encoding null”,即Java虚拟机规范并不强制要求使用一个具体的值编码null。具体根据不同JVM的实现而不同。 null官网中的规范描述
赞![/quote]版主 你的标题错了啊 应该是java中的null 而不是你写的java中的Null 改一下吧
加载更多回复(18)

67,547

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧