【知识点】Java的值传递——为什么对象在函数里修改了,返回后未修改

问题背景:

今天做题,遇到一个代码判断题,结果一直做错。
题目如下:

public class Point{
	private int x;
	private int y;
	public Point(int x, int y){
		this.x = x;
		this.y = y;
	}
	public void setLocaton(int  x,int y){
		this.x = x;
		this.y = y;
	}
	public static void main(String[] args){
		Point p1 = new Point(0,0);
		Point p2 = new Point(0,0);
		modifyPoint(p1,p2);
		System.out.println(p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
	}
	private static void modifyPoint(Point p1, Point p2){
		Point tempPoint = p1;
		p1 = p2;
		p2 = tempPoint;
		p1.setLocaton(5,5);
		p2 = new Point(5,5);
	}	
}

最终输出结果是什么:

 A. [0,0], [0,0]
 B. [5,5], [0,0]
 C. [0,0], [5,5]
 D. [5,5], [5,5]

正确答案是 B [ 0 , 0 ] , [ 5 , 5 ] B [0,0],[5,5] B[0,0],[5,5]
我百思不得其解,因为我认为modifyPoint(Point p1, Point p2)p1设置为[5,5], p2新建且初始化为[5,5],应该输出D选项。

在查询过程中,发现值传递和引用传递的说法:

  • 值传递: 就是复制,把数据传过去, 形参, 函数内操作不改变原来的变量
  • 引用传递:类似指针,传的地址, 要改变操作一起改变。

并且还有JAVA只有值传递的说法, 我一开始也没懂,直到把对象的内存地址打印出来才明白。

建议使用这个自己跑一下,体会下菜鸟JAVA在线编程环境

public class Point{
	private int x;
	private int y;
	public Point(int x, int y){
		this.x = x;
		this.y = y;
	}
	public void setLocaton(int  x,int y){
		this.x = x;
		this.y = y;
	}
	public static void main(String[] args){
		Point p1 = new Point(0,0);
		Point p2 = new Point(0,0);
        
        System.out.println("p1 内存地址="+System.identityHashCode(p1));
        System.out.println("p2 内存地址="+System.identityHashCode(p2));

		System.out.println("1>>>"+p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
		modifyPoint(p1,p2);
		System.out.println("函数后 p1 内存地址="+System.identityHashCode(p1));
        System.out.println("函数后 p2 内存地址="+System.identityHashCode(p2));
		
		System.out.println("7>>>"+p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
		System.out.println("------->"+p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
	}
	private static void modifyPoint(Point p1, Point p2){
        System.out.println("函数内 p1 内存地址="+System.identityHashCode(p1));
        System.out.println("函数内 p2 内存地址="+System.identityHashCode(p2));

		Point tempPoint = p1;
        System.out.println(
        "函数内 temp 内存地址="+System.identityHashCode(tempPoint));
		System.out.println("2>>>"+p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
		p1 = p2;
		System.out.println(
		"p1=p2操作,  p1 内存地址="+System.identityHashCode(p1));
		System.out.println("3>>>"+p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
		p2 = tempPoint;
		System.out.println(
		"p2=temp操作, p2 内存地址="+System.identityHashCode(p2));
		System.out.println("4>>>"+p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
		p1.setLocaton(5,5);
		System.out.println(
		"p1.set操作, p1 内存地址="+System.identityHashCode(p1));
		System.out.println("5>>>"+p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
		p2 = new Point(5,5);
		System.out.println(
		"p2 = new 操作,  p2 内存地址="+System.identityHashCode(p2));
		System.out.println("6>>>"+p1.x+" "+p1.y+";;"+p2.x+" "+p2.y);
	}
	
}

输出结果为:

p1 内存地址=225534817
p2 内存地址=640070680
1>>>0 0;;0 0
函数内 p1 内存地址=225534817
函数内 p2 内存地址=640070680
函数内 temp 内存地址=225534817
2>>>0 0;;0 0
p1=p2操作,  p1 内存地址=640070680
3>>>0 0;;0 0
p2=temp操作, p2 内存地址=225534817
4>>>0 0;;0 0
p1.set操作, p1 内存地址=640070680
5>>>5 5;;0 0
p2 = new 操作,  p2 内存地址=1421795058
6>>>5 5;;5 5
函数后 p1 内存地址=225534817
函数后 p2 内存地址=640070680
7>>>0 0;;5 5
------->0 0;;5 5

关键看着几步:

2>>>0 0;;0 0
p1=p2操作,  p1 内存地址=640070680  !!这里p1指向了原来p2指向的内存地址
3>>>0 0;;0 0
p2=temp操作, p2 内存地址=225534817  !!p2指向了temp指向的内存地址
4>>>0 0;;0 0
p1.set操作, p1 内存地址=640070680    
5>>>5 5;;0 0    
p2 = new 操作,  p2 内存地址=1421795058 !!新内存地址
6>>>5 5;;5 5

然而由于值传递,函数外的对象指针,内存地址并没有变:

函数后 p1 内存地址=225534817
函数后 p2 内存地址=640070680
7>>>0 0;;5 5

所以输出结果的时候,正好是【0,0】,【5,5】

在这里插入图片描述

总结:

JAVA 函数 对象,传的是地址, 交换的也是地址,做好这个对应就行。(我居然蠢到打印了内存地址,才反应过来)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值