java的引用明明和指针没什么本质区别,java为什么还宣称没有指针
指针是抽象意义上的引用的一种,指针看起来和一般的引用那么不一样,主要是因为他的语法不一样,解引用的时候要用一个运算符,其实就是一种引用。new 和 malloc 出来的非数组对象返回的指针,还有作为函数参数让函数修改指向对象的指针,他们的作用就像一般的引用。只不过C/C++里还给了它指针运算的能力,让他提供访问数组元素(还有动态分配的数组)、传递数组作为函数参数的效果。
指针的这种特性引入的目的据说大概也许可能是这样可以减少开销,因为一般的实现里把数组复制一遍按值传递开销是很大的,数组访问也可以用指针算术(汇编里就变成整数加减法或者某些指令里寻址直接可以完成)完成。
那么指针有什么问题?最初引入这些特性就是为了效率,当然不能引入边界检查再去拖累回来,不去检查指针会不会超过数组的边界。指针作为引用乱传来传去,传入函数的时候你也没有给编译足够的信息让他知道你是想传递一个比较大的对象给函数,同时不让他修改,还是要给他一个地方让他返回结果,还是想传递一个数组,编译器不能在编译的时候搞清楚这个指针应不应该允许他做指针算术(加加减减)。你传递两个指针让他们相减的时候,你也不知道他们是不是在同一个数组里。你不恰当使用指针就会出现一些很麻烦的后果,首先程序本身就不正确,而且指针造成的错误可以不局限在使用指针的地方。
更糟糕的是,即使在运行时你也不是很能搞得清楚状况,还是为了效率,C/C++ 把那些不太正确的指针用法,比如解引用空指针、野指针,计算指向不同数组元素指针的差之类的,算作未定义行为(Undefined Behavior)。原因是允许编译器假定这些糟心事情不会发生,进行一些不考虑这种问题会不会存在的优化。也就是说每次你做了“未定义行为”,程序的表现不需要保持一致这也让你很难 debug。到时候可能出现段错误,吐核,彩虹小马从天而降请你吃冰淇淋等等表现,也不排除你的电脑当场爆炸(引用的用烂的玩笑
总之,指针同时承载太多功能,这些功能间的区别也没有反映在编译时候给出的任何信息上(编译器看不懂你的注释也不会去理解你代码的意图),你自己也容易搞糊涂,还有个 UB 的问题在盯着你。
java 有了一些机制可以代替掉 C/C++ 中指针去承载那些功能,也不那么“过分”注重性能,不需要有额外功能的引用,可以避免指针带来的那些麻烦事,所以 java 没有指针也算优点。你要说有什么本质区别的话,就是java的引用更像引用。
PS:指针还有一个问题,所指向的对象的所有权。指针指向对象的所有权不能反映在程序里,只记在程序员脑中、注释里、文档上,编译器不能自己分析出来有没有正确处理这些问题到底该不该 free/delete 掉?谁来 free/delete ?这涉及到的其实是资源管理问题,java 的解决方案是 GC。
查看评论 回复
"java的引用明明和指针没什么本质区别,java为什么还宣称没有指针"的相关文章
- 上一篇:静态内部类和非静态内部类的区别
- 下一篇:码农将一个Javaclass“杀”了