java 传递对象_关于Java对象作为参数传递是传值还是传引用的问题

前言

在Java中,当对象作为参数传递时,究竟传递的是对象的值,还是对象的引用,这是一个饱受争议的话题。若传的是值,那么函数接收的只是实参的一个副本,函数对形参的操作并不会对实参产生影响;若传的是引用,那么此时对形参的操作则会影响到实参。

首先我们来看一句代码:

Object obj = new Object();

这句话的意思是:创建一个Object对象,再创建一个名为obj的引用,让这个引用指向这个对象,如下图所示:

d311d893107a2a1c154800186c7680f1.png

在有了上面的基础之后,我们便来看下面这组在网上很流行的例子:

基本数据类型作为参数传递:

例1:

public classtest {public static voidmain(String[] args) {int i = 1;

System.out.println("before change, i = "+i);

change(i);

System.out.println("after change, i = "+i);

}public static void change(inti){

i= 5;

}

}

这个例子不难理解,当基本数据类型(Boolean,byte,char,String,int,Long,float,double)作为参数传递时,传递的是实参值的副本,即传的是值,无论在函数中怎么操作这个副本,实参的值是不会被改变的。所以以上代码执行的结果是:

before change, i = 1after change, i= 1

对象作为参数传递:

在下面的例2中,我们把StringBuffer对象作为参数传递到change函数。

例2:

public classtest {public static voidmain(String[] args) {

StringBuffer sb= new StringBuffer("Hello ");

System.out.println("before change, sb is "+sb.toString());

change(sb);

System.out.println("after change, sb is "+sb.toString());

}public static voidchange(StringBuffer stringBuffer){

stringBuffer.append("world !");

}

}

为了方便推理出结论,我们先直接看程序的运行结果:

before change, sb is Hello

after change, sb is Hello world!

从输出结果中我们可以发现,sb所指向的对象的值被改变了,那么是否我们可以推论出,在Java中,当对象作为参数传递时,传递的是该对象的引用呢?我们再来看下面这个例子:

public classtest {public static voidmain(String[] args) {

StringBuffer sb= new StringBuffer("Hello ");

System.out.println("before change, sb is "+sb.toString());

change(sb);

System.out.println("after change, sb is "+sb.toString());

}public static voidchange(StringBuffer stringBuffer){

stringBuffer= new StringBuffer("Hi ");

stringBuffer.append("world !");

}

}

如果上面的推论是正确的,即Java中对象作为参数传递,实际传递的是该对象的引用,那么在调用change函数之后,原对象的值应该是会改变的,变为“Hi world !”,但是,当我们运行程序后,结果却是如下所示:

before change, sb is Hello

after change, sb is Hello

原对象的值并没有被改变,这与上面的推论相矛盾!为什么在Java中,当对象作为参数传递时,有的时候实参被改变了,而有的时候实参并未被改变呢?下面让我们来分析一下其中的原因:

从文章的开头我们知道,当执行StringBuffer sb = new StringBuffer(“Hello “)时,我们创建了一个指向新建对象“new StringBuffer(“Hello “)”的引用“sb”,如下图所示:

3f28f11f1e088dc6ea5d063e43e218ef.png

在例2中,当我们调用change函数后,实际上,形参stringBuffer也指向了实参sb所指向的对象,即:

c6e75c27ae9b347a90de49da600a4894.png

那么当我们执行stringBuffer.append(“world !”)后,便通过对象的引用“stringBuffer”修改了对象的值,使之变成了“Hello world !”,即:

4ce2217ff118b51f70d28de75869051e.png

但是,在例3中的change函数中,我们又新建了一个对象“new StringBuffer(“Hi “)”(这实际上在内存中开辟了一块在原对象地址之外的新区域),这让形参stringBuffer实际指向了这个新建的对象,并将新对象的值设置为“Hi world !”,例三中stringBuffer的值已经被改变为了Hi world,但是因为值没有被return返回赋值给sb对象,所以sb对象并没有被改变,所以输出的任然是hello,即:

f1e3362be970b6a594bc417412a35b6a.png

那么我们就不难理解,为何在执行完change函数之后,实参的值仍为“Hello”了。

结论

综上所述,我们可以得出结论:在Java中,当对象作为参数传递时,实际上传递的是一份“引用的拷贝”。 (实际传递的是对象的引用)

转载自:https://blog.csdn.net/xiangwanpeng/article/details/52454479

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中实现两个窗体间的数据传递可以通过构造函数、setter方法和接口回调实现。 1. 构造函数传值 假设有两个窗体A和B,需要将A中的数据传递给B,可以在B的构造函数中添加参数,将A中的数据传递给B。 在A中: ```java public class A { private String data; private B b; public A() { b = new B(data); } } ``` 在B中: ```java public class B { private String data; public B(String data) { this.data = data; } } ``` 2. setter方法传值 如果A中的数据需要在B中动态改变,可以使用setter方法进行传值。 在A中: ```java public class A { private String data; private B b; public void setData(String data) { this.data = data; b.setData(data); } } ``` 在B中: ```java public class B { private String data; public void setData(String data) { this.data = data; } } ``` 3. 接口回调传值 在A中定义一个接口,B实现该接口,并将B的实例作为参数传递给A。当A中的数据发生变化,调用接口中的方法通知B更新数据。 在A中: ```java public interface DataChangeListener { void onDataChange(String data); } public class A { private String data; private DataChangeListener listener; public void setListener(DataChangeListener listener) { this.listener = listener; } public void setData(String data) { this.data = data; if (listener != null) { listener.onDataChange(data); } } } ``` 在B中: ```java public class B implements DataChangeListener { private String data; @Override public void onDataChange(String data) { this.data = data; } } ``` 通过以上三种方式,可以实现Java中两个窗体之间的数据传递

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值