Java 新手进阶:细说引用类型(编程随想的博客)

  在前几天的帖子《Java性能优化[1]:基本类型 vs 引用类型》里,俺大概介绍了“引用类型”与“基本类型”在存储上的区别。昨天有网友在评论中批评说“引用类型变量和它所引用的对象”没区分清楚,容易混淆。所以今天专门来说一下引用类型的相关细节。
  另外,顺便也把原先的帖子中,关于“两种类型的存储方式”这节补充了一下,加点插图,有助于大伙儿的理解。
  其实,引用类型的变量非常类似于 C/C++ 的指针。为了形象起见,也为了打字方便,本文后面的内容,都把“引用类型的变量”称为【指针】。所以,如果你原先有 C/C++ 背景,今天讲的内容对你来说应该很好理解;否则的话,可能要多琢磨琢磨了。

★创建问题

  假设咱们在【函数中】写了如下这个简单的语句:

StringBuffer str = new StringBuffer("Hello world");

  别看这个语句简单,其实包含了如下三个步骤:
  首先,new 操作符会在【堆】(Heap)里申请了一坨内存,把创建好的 StringBuffer 对象放进去。
  其次,StringBuffer str 声明了一个指针。这个指针本身是存储在【栈】(Stack)上的(因为前面俺说了:此语句写在【函数中】),用来指向某个 StringBuffer 类型的对象。或者换一种说法,这个指针可以用来保存某个 StringBuffer 对象的地址。
  最后,当中这个 等于号(赋值符号)把两者关联起来,也就是把刚申请的那一坨内存的地址保存成 str 的值。

  为了加深列位看官的印象,把上次那篇帖子的图片再拿出来秀一下:

★引用对象之间的赋值、判相等

  通过上述的图解,大伙儿应该明白指针变量和该指针变量指向的【对象】是一个什么关系了吧?
  还是接着刚才的例子,再来看赋值的问题。对于如下语句:

StringBuffer str2 = str;

  这个赋值语句是啥意思捏?实际上就是把 str 的地址复制给 str2;记住,是地址的复制,StringBuffer 对象本身并【没有】复制。所以两个指针指向的是同一个东东。
  再搞一张示意图,如下(今天画这些图可把俺累坏了):

  明白了赋值,判断相等的问题(就是==操作符)也就简单了。当我们写如下语句时,只是判断两个指针的【值】(也就是对象的地址)是否相等,并【不是】判断“被指向的对象”是否内容相同。

if(str2 == str)

  实际上两个指针的值相同,则肯定是指向同一个对象(所以对象内容必定相同)。但是两个内容相同的对象,它们的地址可能不一样(比如克隆出来的多个对象之间,地址就不同)。

★final 常量的问题

  针对引用类型变量的 final 修饰符也是很多人搞混淆的地方。实际上 final 只是修饰指针的值(也就是限定指针保存的地址不能变)。至于该指针指向的对象,内容是否能变,那就管不着了。所以,对于如下语句:

final StringBuffer strConst = new StringBuffer();

  你可以修改它指向的对象的【内容】,比如:

strConst.append("hello world");

  但是【不能】修改它的【值】,比如:

strConst = null;

★传参的问题

  引用类型(在函数调用中)的传参问题,是一个相当扯的问题。有些书上说是传值,有些书上说是传引用。搞得 Java 程序员都快成神经分裂了。所以,我们最后来谈一下“引用类型参数传递”的问题。
  还是拿刚才的例子,假设现在要把刚才创建的那一坨字符串打印出来,我们会使用如下语句:

System.out.println(str);

  这个语句又是什么意思捏?这时候就两说了。
  第一种理解:
  可以认为传进函数的是 str 这个指针,指针说白了就是一个地址的值,说得再白一点,就是个整数。按照这种理解,就是传值的方式。也就是说,参数传递的是指针本身,所以是传值的。
  第二种理解:
  可以认为传进去的是 StringBuffer 对象,按照这种理解,就是传引用方式了。因为我们确实是把对象的地址(也就是引用)给传了进去。
  费了这么多口水,其实不论是“传引用”还是“传值”,都可以讲得通,关键取决于你是【如何看待】参数所传递的【东西】。这就好比量子力学中“光的波粒二象性”,如果你以粒子的方式去测量它,它看起来像粒子;如果你以波动的方式去观测它,它看起来像波动。假如你不太懂量子力学,前面这话就当我没说 :-)

时间: 2024-08-28 18:00:22

Java 新手进阶:细说引用类型(编程随想的博客)的相关文章

Java 新手的通病(编程随想的博客)

一:对算法和数据结构不熟悉 为什么我先拿"数据结构和算法"说事捏?这玩意是写程序最最基本的东东.不管你使用 Java 还是其它的什么语言,都离不开它.而且这玩意是跨语言的,学好之后不管在哪门语言中都能用得上. 既然"数据结构和算法"这么重要,为什么很多 Java 新手却很不熟悉捏?我琢磨了一下,估计有两种可能.有些人虽然是计算机系毕业的,但是当初压根没好好学过这门课程,到工作时早都还给老师了:还有一些人是中途转行干编程,转行后又没有好好地打基础(都指望速成). 下面

如何挖掘网络资源(编程随想的博客)

一:网站的类型和使用场景 首先来介绍一下网站的类型和特点.不同的网站特点将决定你挖掘资源的方式. ★网站内容的指标 要挖掘互联网的资源,首先需要关注网站的内容.俺大致总结了几个指标,任何网站的内容,都具有这几个指标. 通过这些指标,可以评估某个网站[对你的价值]到底有多大,还可以评估你挖掘其中的内容需要耗费多少时间和精力. ◇内容的信噪比 任何一个网站的内容,都会有一些信息是无用的,咱们称之为"噪声".所谓的[信噪比],就是是"有用信息"与"垃圾噪声&qu

Java 性能优化(编程随想的博客)

考虑写性能优化系列,主要是因为之前看到了太多性能其烂无比的 Java 代码(有些代码看得俺口瞪目呆).很多 Java 程序员在写程序时,由于不太了解 JVM 及语言本身的一些运作机制,从而导致了代码的性能出现[严重]问题(性能差一个数量级以上,我才称为"严重"). 虽然网上也有针对 Java 性能的介绍,但是很多内容都仅仅告诉读者"该这么做",而没有讲"为什么该这么做".典型的例子就是关于 String 和 StringBuffer(String

我的Android进阶之旅------>经典的大牛博客推荐(排名不分先后)!!

本文来自:http://blog.csdn.net/ouyang_peng/article/details/11358405 今天看到一篇文章,收藏了很多大牛的博客,在这里分享一下 谦虚的天下 柳志超博客 Android中文Wiki AndroidStudio-NDK开发-移动开发团队谦虚的天下 - 博客园gundumw100博客 - android进阶分类文章列表 - ITeye技术网站CSDN博文精选:Android系列开发博客资源汇总 - CSDN.NET - CSDN资讯Android笔

Java新手进阶:细说引用类型

在Java中,引用类型的变量非常类似于C/C++的指针.本文为新手进阶教程,为大家详细介绍引用的类型. 为了形象起见,也为了打字方便,本文后面的内容,都把“引用类型的变量”称为指针.所以,如果你原先有C/C++背景,今天讲的内容对你来说应该很好理解:否则的话,可能要多琢磨琢磨了. ◆创建Java进阶问题 假设我们在函数中写了如下这个简单的语句: StringBuffer str = new StringBuffer("Hello world"): 别看这个语句简单,其实包含了如下三个步

编程技巧及博客资源

1. 我的iOS高效编程秘诀—坚持编程习惯  http://www.jianshu.com/p/a649847f781a 2.iOS学习路线201511---201603 http://www.jianshu.com/p/6f917f3a5d46 3.iOS及Mac开源项目和学习资料[超级全面]http://www.kancloud.cn/digest/ios-mac-study/84557  http://github.ibireme.com/github/list/ios/# 4.Bison

10个值得推荐的学习编程的网站————博客园

/10个值得推荐的学习编程的网站 世界已经进入了互联网的时代.据最近发布的一篇<2016年互联网趋势>报告显示,中国已成为互联网市场的领导者,中国互联网用户的数量达到了6.68亿.可以预见,有着如此巨大的市场潜力,中国的互联网产业会迎来又一个井喷式的高峰.行业的迅猛发展也会相应地刺激行业人才的发展.据不完全统计,目前中国互联网从业人员的数量达到了5000多万人.从细分行业来看,互联网从业人员集中在移动互联网和电子商务这两大领域,岗位以技术类和运营类为主.其中,编程开发人员是技术类岗位的主力军,

java 反射机制(我的第一篇博客)

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”.从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言.但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时

Java生成和操作Excel文件 - 残星 - 博客园 (2)

body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI",Tahoma,Helvetica,Sans-Serif,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLiU,serif; font-size: 10.5pt; line-height: 1.5;