我是先学习的C++再学习的Java,这样的路线会让我在学习Java的时候省下很多功夫,但是也给我带来了挺多困扰 一个很大的问题就是两者对待引用数据类型的态度区别很大。 Java为了考虑安全,删除了指针这种危险东西;而C++,指针使它最锋利的武器。 抛下了指针之后,Java变成了一个事事围绕对象的语言。 这样的设计方向,使得一些思想与设计模式与C++迥然不同
比如,什么是null?
Null pointer This macro expands to a null pointer constant.
在C++11中,NULL是这么定义的
A null-pointer constant is either an integral constant expression that evaluates to zero (such as 0 or 0L), or a value of type nullptr_t (such as nullptr). ——c++ reference
- 对于Java来说,null代表一个不确定的引用类型
我们都知道Java的对象都是object类的子类。但是,null并不是object的一个实例,也不是0,null就是null,null就是空。
那么说了这么多,C++和Java中的null到底有什么区别呢? 别急,且听我给你举个栗子
我们写程序免不了创建对象。要知道,创建一个对象而不赋初值其实是一个不太好的习惯。在C++中,我们习惯这么赋初值
vector<int> v=NULL;
这样会报出编译错误,因为人家明明是一个vector类,你却给人家一个空指针,这怎么行? 但是我们可以吧一个相应类型的空指针指向引用类型,并使用者这个指针进行相应的操作。
而在Java中,由于引用数据类型的关系,如果你给一个类赋初值为null,则不会出错
List<int> list=null;
但是不出错不代表没有问题 如果你在没有为list一个新的实例的情况下使用这个变量
list.add(1);
则会出现nullPointerException 因为你这个list没有任何实例,它本质上是null,也就是空。 但是,一个空的数组,与一个null是有本质上的区别的 {}是一个list的实例,而null是空 所以,我们要尽量避免在赋值时赋值为null,当然,这样做最终是为了防止我们编写的API最后将null传给使用这个API的用户
如果我们传给用户的值是一个空数组,那么,用户编写的代码(如add,遍历等操作)都可以正常执行。但是如果我们传递了一个null,那么,如果用户试图调用null的任何方法,都会报出空指针异常,这样就使得用户必须写一段特定的代码来处理null,增加了额外的开销 但是这还不是最糟的! 如果你的程序只有在非常罕见的情况下才返回一个null,那么,当用户发现程序会产生nullPointerException时可能已经是在程序投入使用时,这时再进行debug则会产生巨大的成本与开销。 而一个空数组,则是相对无害、安全的,是符合Java设计模式与目的的,所以,我强烈建议大家在初始化数组时使用空数组而非null!
|