我在完成我的第一个项目的时候就遇到过这个问题。我在centlingZiller(公司一个内部的系统,可以查看代码的diff,comment) 上看到一个同事(哈哈哈,我们是同学)的一段代码。Account a=(Account) session.getAttribute("user"); ,我就在diff下面评论session.getAttribute("user"); 为null 时强转不会失败吗?没过多久,我看到另一条评论,回复我,null 可以强转成任意引用类型。
于是我写个测试了下,发现确实如此。
但是为什么呢?下面一句话解决战斗。
当我们定义一个引用对象的时候,如 User u ; 这时候会在栈中分配一个内存内存空间,这时候改对象是不能被使用的。为什么不能被使用呢?
让我们分析,栈中的这个 u ,这块内存至少包括两部分,一个是类型,一个是地址,地址就是类型为User的指针指向的堆空间,当变量未被初始化的时候,该地址空间 为null或垃圾地址 ,当你要使用该变量的时候,是不是像C++那样 *p 取值,但是*垃圾地址 是非法的,说到这里大家可能明白了吧,Java中为什么不允许使用未经初始化的引用变量了吧。
接着说, 当我们在 代码中这样定义 A a;B b;a, b 有什么区别呢?他们都在栈中,他们类型不一样,地址域也不一样。地址域为什么不一样?
因为地址域所在的内存空间,存放的可能是一块垃圾地址。所以当你先使用变量的时候要么给他 赋值为null,要么给他一块有用的可控的地址。
接着说, A a =null;B b=null;a, b有什么区别? 大家可能看出来了,他们只是类型不一样,地址域一样。
让我们在想想我们最初的问题,null 为什么可以被转换成任意引用类型?是不是豁然开朗?
突然想到这个问题,记录一下供大家参考。新手技术尚浅,如有错误,还请指正。