java 所谓的值传递和引用传递
来源:互联网 发布:开淘宝网店发货图片 编辑:程序博客网 时间:2024/06/05 17:44
最近学校课程java上了一半,我发现我一直都不太懂值传递,引用传递什么的,这次一定要弄懂
先从最开始谈吧
一、什么叫做值传递与引用传递
实参与形参
- 存储单元(左值)
- 存储内容(右值)
根据所传递的实参的“内容”,参数传递可分为:
- 传值调用:传递实参的右值到形参单元;
- 引用调用:传递实参的左值到形参单元;
- 值-结果调用:传递实参的右值;在控制返回时将右值写回到实参相应左值单元(如果有的话);
- 换名调用:传递实参的“正文”。
以下是值传递
以下是地址传递
以下为地址传递
eg:
- void Exchg2(int *px, int *py)
- {
- int tmp = *px;
- *px = *py;
- *py = tmp;
- printf("*px = %d, *py = %d.\n",*px, *py);
- }
- main()
- {
- int a = 4,b = 6;
- Exchg2(&a, &b);
- printf("a = %d, b = %d.\n", a,b);
- return(0);
- }
- void Exchg3(int &x, int &y)
- {
- int tmp = x;
- x = y;
- y = tmp;
- printf("x= %d,y = %d\n", x, y);
- }
- main()
- {
- int a = 4,b =6;
- Exchg3(a, b);
- printf("a= %d, b = %d\n", a, b);
- return(0);
- }
这个道理大家都懂,那么在java中是如何运作的呢?
二、java专场
句柄概念
java并没有c++中指针、地址的概念,它只有句柄(handler)的概念。还以凤舞凰扬的两个方法为例:
public void call(Test t) {
Test t2 = new Test();
t2.setName("cba');
t.setName("abc");
t = t2 ;
}
public static void main(String[] arg) {
Test obj = new Test();
call (obj) ;
System.out.println("obj"+obj.getName());
}
总共构建了两个Test对象,假设称main方法构建的对象为“对象1”,call方法构建的对象为“对象2”,
在main方法中,变量obj获得了“对象1”的句柄,
在参数传递中,变量obj把这个句柄传递给变量t,
在call方法中,变量t首先改变了“对象1”的属性,然后变量t又获得了“对象2”的句柄(但obj仍然是“对象1”的句柄),
call方法返回后,由于“对象2”失去了唯一的句柄,不可避免的进入垃圾收集器的视线。而obj仍然是“对象1”的句柄,由于“对象1”的属性已经被重新设置,所以我们可以看到打印出来的结果是“abc”。
我更喜欢下面这个例子
一个句柄的传递会使调用者的对象发生意外的改变。
public class Testit {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
System.out.println("after swap: " + "a=" + a + " name: " + a.getName());
}
private static void swap(Testit swap1, Testit swap2) {
System.out.println(" swaping: " + "a=" + a + " name: " + a.getName());
STestit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
swap1.setName("a's name");
swap2.setName("b's name");
}
}
before swap: a=com.lib.Testit@16930e2 name: a
swaping: a= com.lib.Testit@16930e2 name: a
after swap: a=com.lib.Testit@16930e2 name: b's name
我们看到,a依旧是原来那个a,但name却不是原来那个name了!
在swap()方法中,swap1和swap2互相换过来了,这个时候swap2指向的是a,所以在setName()的时候改变的是a的name,而不是b的name。
为什么会这样呢?
Java里的传值实际上是拷贝引用,而不是拷贝对象。
浏览了很多博主的总结我看到下面几句话
1、java只有值传递方式
2、在Java中方法参数的传递,对象是传递引用,基本数据类型是传递值()
3、java传递是引用的拷贝,既不是引用本身,更不是对象
总的来说,我接受这样的说法:在java中方法参数的传递,对象是传递引用的拷贝,基本类型是传递值
如有错误,希望指证,谢谢
本人总结的不好,大家可以看一看这位大神的,还有这个 http://blog.csdn.net/faintbear/article/details/198021
http://blog.sina.com.cn/s/blog_59ca2c2a0100qhjx.html#cmt_2041332
点击打开链接
- java 所谓的值传递和引用传递
- 所谓的Java的引用传递
- Java的值传递和引用传递
- java的引用传递和值传递
- java的引用传递和值传递
- Java的引用传递和值传递
- java的值传递和引用传递
- java的值传递和引用传递
- java的值传递和引用传递
- Java的参数传递有值传递和引用传递
- [学习笔记]Java的值传递和引用传递,引用传递转值传递
- java复习-java的值传递和引用传递
- Java的方法的参数传递,值传递和引用传递还有String字符串传递
- Java的值传递和引用值传递的区别
- java的"值传递"和"引用传递"的问题
- 关于Java的值传递和引用传递的总结
- 对于Java的值传递和引用传递的区别
- java中的“值传递”和“引用传递”
- PAT(basic level) 1003 我要通过
- JSP新闻系统之五 增加操作
- 安卓项目,信号检测总结
- caffe学习(2)前后传播,loss,solver
- 基于codebook背景建模的运动目标检测
- java 所谓的值传递和引用传递
- 线性表的应用——约瑟夫环
- windows下开启远程连接Mysql
- 滤波器设计(4):自适应滤波器之最小均方误差(LMS)滤波器的设计
- NavigationView的实例应用
- Java并发---- Executor并发框架--ThreadToolExecutor类详解(execute方法)
- 表单
- Android系列之UI组件----Menu菜单
- Java并发---- Executor并发框架--线程池,ThreadToolExecutor初步理解