首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java基础0405_引用传递及其应用

本次学习的目标

掌握三种引用传递的操作范例

掌握引用传递的应用

具体内容

1.三道引用范例

我们新建项目RefDemo,然后新建类RefDemo01

1.1范例一:

classDemo01{

inttemp=30 ;//这里为了方便,属性暂时不封装

}

publicclassRefDemo01 {

publicstaticvoidmain(String[] args) {

Demo01 d1 =newDemo01() ;//实例化Demo01对象,实例化之后里面的temp=10

d1.temp=50 ;//修改temp属性的内容

fun(d1);

}

publicstaticvoidfun(Demo01 d2){//此处的方法由主方法直接调用

d2.temp= 100;

}

}

运行结果:

这时我们可以看到,temp的值是改变了的。

下面我们来对这个范例进行内存分析:

首先,我们在实例化对象的时候,开辟了一个堆空间,储存temp属性=30,然后我们在主方法中,对temp进行修改为50,然后我们新建了方法fun()在主方法内可以直接调用,而fun()方法所引用的是Demo01中的d1,传给了d2,这时d1,d2所指向的空间是一样的。然后d2对temp进行了修改,执行完后,断开了链接,此时的temp属性的值保留了修改后的值。这跟我们之前讲的数组的引用传递是非常相似的,不难理解。

1.2范例二:

我们新建类RefDemo02

publicclassRefDemo02 {

publicstaticvoidmain(String args[]){

String str1 ="hello";//实例化字符串对象

fun(str1);//调用fun方法

}

publicstaticvoidfun(String str2){

str2 ="MLDN";//修改字符串内容

}

}

运行结果:

我们可以看到结果是没有改变的,下面我们队他进行内存分析

这里需要注意的事,因为String类的值是不可改变的,所以当我们调用fun()方法中str2要修改值时,由于一个栈只能指向一个堆,所以就会断开原先的指向,重新指向一个堆,然后膝盖str2的内容。所以str1的内容并没有修改保留下来。

1.3范例三:

新建类RefDemo03

classDemo02{

Stringtemp="hello";//定义一个属性

}

publicclassRefDemo03 {

publicstaticvoidmain(String args[]){

Demo02 d1 =newDemo02() ;//实例化Demo02对象

d1.temp="world";//修改temp属性的内容

fun(d1);//调用fun方法

}

publicstaticvoidfun(Demo02 d2){//此处的方法由主方法直接调用

d2.temp="MLDN";//修改temp的值

}

}

运行结果:

下面对范例三进行内存分析:

这里可以看到跟我们第一个范例是一样的,而我们第二个范例比较特殊,因为堆里面的内容是String类直接赋值的,而String是一个特殊的类,其内容是不可改变的。

2.接收本类引用

例如,我们新建RefDemo04

classDemo03{//定义Demo03类

privateinttemp= 30;//声明temp属性并封装

publicintgetTemp() {//getter方法

returntemp;

}

publicvoidsetTemp(inttemp) {//setter方法

this.temp= temp;

}

}

publicclassRefDemo04 {

publicstaticvoidmain(String[] args) {

Demo03 d1 =newDemo03();//实例化Demo03对象

d1.setTemp(50);//只能通过setter方法修改内容

d1.temp= 30 ;//如果这样修改内容,肯定会出现错误

}

}

运行结果:

因为此时d1是在Demo03类的外部,所以无法访问,那么如果现在按照引用传递的方式将其传入到其内部的话,就可以相当于自己接收本类的引用对象了。

我们修改一下:

classDemo03{//定义Demo03类

privateinttemp= 30;//声明temp属性并封装

publicvoidfun(Demo03 d2){//接收本类的引用

d2.temp= 60 ;//直接通过对象调用本类的私有属性

}

publicintgetTemp() {//getter方法

returntemp;

}

publicvoidsetTemp(inttemp) {//setter方法

this.temp= temp;

}

}

publicclassRefDemo04 {

publicstaticvoidmain(String[] args) {

Demo03 d1 =newDemo03();//实例化Demo03对象

d1.setTemp(50);//只能通过setter方法修改内容

d1.fun(d1);//此处把Demo03的对象传回到自己的类中

}

}

运行结果:

我们可以看到,只要是符合引用传递的语法,则可以向任意的地方传递;

3.范例讲解:一对一关系

实际上我们在使用引用传递时,还可以表示出生活中的场景,例如:一个人有一本书,一本书属于一个人。从这样一句话中可以得到这样的结论:人应该是一个具体的类、书也应该是一个具体的类,在人的类中应该存在一个属性表示书,在书的类中也应该存在一个属性表示人。

下面我们新建RefDemo05来表示这种场景

classPerson{//定义Person类

privateStringname;//姓名

privateintage;//年龄

privateBookbook;//一个人有一本书

publicPerson(String name,intage){//构造方法,两个属性

this.setName(name);

this.setAge(age);

}

publicString getName() {

returnname;

}

publicvoidsetName(String name) {

this.name= name;

}

publicintgetAge() {

returnage;

}

publicvoidsetAge(intage) {

this.age= age;

}

publicBook getBook() {

returnbook;

}

publicvoidsetBook(Book book) {

this.book= book;

}

}

classBook{//定义Book类

privateStringtitle;//标题

privatefloatprice;//价格

privatePersonperson;//一本书属于一个人

publicBook(String title,floatprice){//构造方法

this.setTitle(title);

this.setPrice(price);

}

publicString getTitle() {

returntitle;

}

publicvoidsetTitle(String title) {

this.title= title;

}

publicfloatgetPrice() {

returnprice;

}

publicvoidsetPrice(floatprice) {

this.price= price;

}

publicPerson getPerson() {

returnperson;

}

publicvoidsetPerson(Person person) {

this.person= person;

}

}

publicclassRefDemo05 {

publicstaticvoidmain(String[] args) {

Person per =newPerson("张三",30) ;//实例化对象

Book bk =newBook("Java基础",99.0f);

per.setBook(bk);//设置两个对象间的关系,一个人有一本书

bk.setPerson(per);//设置两个对象间的关系,一本书属于一个人

+",年龄:"+ per.getAge() +",书名:"+ per.getBook().getTitle()

+",价格:"+ per.getBook().getPrice());//通过人名找到书

+",价格:"+ bk.getPrice() +",人名:"+ bk.getPerson().getName()

+",年龄:"+ bk.getPerson().getAge());//通过书名找到人

}

}

运行结果:

可以看到我们应用在场景的这个基本关系。

下面我们进一步的深入进去,再添加一些关系进去:比如一个人有一个孩子,每个孩子还会有一本书,按照我们上面的思路,难道还有建多一个孩子的类吗?很明显这样是不可取的,因为孩子也是属于人的范围,所以我们只需要修改Person类即可,下面我们复制一下RefDemo05的代码,在RefDemo06进行修改,在类中增加一个自己的引用。

因为我们在Eclipse中,在同个项目中,不同类使用同样的类名是会报错的,所以我们也将Person改为Person1,Book改为Book1。

classPerson1{//定义Person类

privateStringname;//姓名

privateintage;//年龄

privateBook1book;//一个人有一本书

privatePerson1child;//一个人有一个孩子

publicPerson1(String name,intage){//构造方法,两个属性

this.setName(name);

this.setAge(age);

}

publicString getName() {

returnname;

}

publicvoidsetName(String name) {

this.name= name;

}

publicintgetAge() {

returnage;

}

publicvoidsetAge(intage) {

this.age= age;

}

publicBook1getBook() {

returnbook;

}

publicvoidsetBook(Book1book) {

this.book= book;

}

publicPerson1getChild() {

returnchild;

}

publicvoidsetChild(Person1child) {

this.child= child;

}

}

classBook1{//定义Book类

privateStringtitle;//标题

privatefloatprice;//价格

privatePerson1person;//一本书属于一个人

publicBook1(String title,floatprice){//构造方法

this.setTitle(title);

this.setPrice(price);

}

publicString getTitle() {

returntitle;

}

publicvoidsetTitle(String title) {

this.title= title;

}

publicfloatgetPrice() {

returnprice;

}

publicvoidsetPrice(floatprice) {

this.price= price;

}

publicPerson1getPerson() {

returnperson;

}

publicvoidsetPerson(Person1person) {

this.person= person;

}

}

publicclassRefDemo06 {

publicstaticvoidmain(String[] args) {

Person1per =newPerson1("张三",30) ;//实例化对象

Person1cld =newPerson1("张四",10) ;//定义一个孩子

Book1bk =newBook1("Java基础",99.0f) ;//定义书

Book1bo =newBook1("十万个为什么",33.3f) ;

per.setBook(bk);//设置两个对象间的关系,一个人有一本书

bk.setPerson(per);//设置两个对象间的关系,一本书属于一个人

cld.setBook(bo);//设置对象间的关系,一个孩子有一本书

bo.setPerson(cld);//设置对象间关系,一本书属于一个孩子

per.setChild(cld);//设置对象间关系,一个人有一个孩子

+",年龄:"+ per.getAge() +",书名:"+ per.getBook().getTitle()

+",价格:"+ per.getBook().getPrice());//通过人名找到书

+",价格:"+ bk.getPrice() +",人名:"+ bk.getPerson().getName()

+",年龄:"+ bk.getPerson().getAge());//通过书名找到人

//通过人找到孩子,并找到孩子所拥有的书

+ per.getChild().getName() +",年龄:"+ per.getChild().getAge()

+",书名:"+per.getChild().getBook().getTitle() +",价格:"

+per.getChild().getBook().getPrice());

}

}

运行结果:

可以看到对应的关系也找了出来,对于代码的修改,在有标记的地方要主要修改。

总结

我们上面所有的应用范例,现在为止只是完成了一些比较细小的模型,但是这些模型都将成为日后JAVA EE开发中最重要的部分。希望可以反复理解引用传递的关系,并可以利用引用传递完成一些小的关系模型。

关爱IT人,关注挨踢栏

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180129A0MGV400?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券