- 名师讲坛:Java开发实战经典(第2版)
- 李兴华
- 1542字
- 2021-03-23 23:37:53
5.8 引用传递及基本应用
在实际的开发之中,引用传递又有着非常重要的作用,本节将针对引用传递的使用进行完整分析,同时介绍引用传递在实际开发中的操作意义。
5.8.1 引用传递分析
前面的概念已经为读者介绍了引用传递的基本概念,所谓的引用传递就是指将堆内存空间的使用权交给多个栈内存空间,下面通过3道范例让读者加深对前面所学引用知识的理解。
1.引用传递范例1
【例5.37】对象引用传递
程序执行结果:
从以上的运行结果可以发现,在fun()方法之中接收了Demo类对象d1,并将里面的temp属性的内容进行修改,因为是引用传递,所以最终temp的值是1000,此程序可以通过图5-17表示。
图5-17 引用传递范例的内存分析图1
提示
初学者要多画图以加深理解。
对于引用传递的操作,初学者应该多拿纸笔将内存的分配图形完整的描绘出来,这样可以假设对于引用传递操作步骤的理解,为后续的学习打下基础。
以上的代码操作实际上与之前的向方法中传递数组的操作过程是一致的,了解了以上的范例之后,再来看一下下面的程序,再观察结果。
2.引用传递范例2
【例5.38】引用传递
程序执行结果:
从程序运行结果中发现,虽然此时传递的是一个String类型的对象,但是结果并没有像之前那样发生改变,因为字符串的内容一旦声明是不可改变的,改变的只是其内存地址的指向,本程序的内存操作如图5-18所示。
图5-18 引用传递范例的内存分析图2
以上的操作代码并不难理解,因为每一个字符串对象都表示一个匿名对象,这样在fun()方法操作之中,如果为str2重新设置内容,就相当于改变了str2的引用,而str1本身的内容并不会受任何影响。
3.引用传递范例3
清楚了前面的两个范例之后,下面再来看一下第3个范例,下面的程序读者可以先自行分析运行结果。
【例5.39】引用传递
程序执行结果:
本程序运行后,发现在fun()方法中将属性的内容修改了,内存操作如图5-19所示。
读者从图5-19中可以清楚地发现,本道题目的分析方法与第一道是完全一样的,因为String是作为一个Demo类的属性存在的,而在操作的时候更改的只是Demo类中属性的内容。
图5-19 引用传递范例的内存分析图3
5.8.2 接收本类的引用
以上为引用传递的基本形式,实际上在对象引用传递上也可以在一个类中接收自己本类对象的实例。而且接收完之后,可以方便地通过此对象直接进行本类中封装属性的访问,如下面的代码。
【例5.40】接收自己本类的对象
程序执行结果:
有些读者会认为这样做有些不合理,因为私有属性不应该被对象所访问,但是另一方面因为是在类的内部,所以可以访问里面的私有属性,因此只要是符合了引用传递的语法,则可以向任意的地方传递。
提示
在对象比较的时候才会使用。
此种引用方式的传递之后在随后讲解关于对象比较操作的时候才会使用,其他时候基本上都很少使用。
5.8.3 范例1——一对一关系
实际上使用引用传递还可以表示出生活中的以下一种场景,例如:一个人有一本书,一本书属于一个人。因而可以得出这样的结论:人应该是一个具体的类、书也应该是一个具体的类,在人的类中应该存在一个属性表示书,在书的类中也应该存在一个属性表示人。
【例5.41】代码实现
程序执行结果:
从上面程序的运行结果中可以清楚地发现,人和书有了关联关系,如图5-20所示。
图5-20 类图关系
技术穿越:简单Java类的初步定义。
读者可以发现,以上所给出的Person类与Book类的组成都包括:属性、构造方法、setter和getter方法,而这样组成的类在实际的开发中往往会称为简单Java类。
同时对于简单Java类也有许多的名称,例如POJO(Plain Ordinary Java Object)、VO(Value Object)、PO(Persistent Object)、TO(Transfer Object)。
5.8.4 范例2——进一步深入一对一关系
以上已经完成了一个基本的关系,但是现在有了一个新的要求:一个人有一个孩子,每个孩子还会有一本书,该如何分析呢?难道再单独建立一个孩子的类吗?很明显这样做是不可取的,因为一个孩子也是一个人。此时,只需要简单地修改Person类即可,在类中增加一个自己的引用。
【例5.42】对程序进行扩展
程序执行结果: