用简单易懂的概念彻底理解Java值传递

       对于Java初学者来说,Java的值传递可能是学习Java遇到的第一个比较难以理解的概念,一般在初次接触这个概念的时候,会从基本数据类型和引用数据类型进行区分,由此也引出了关于“Java值传递与引用传递”一说,随着深入理解java的传参机制,笔者认为java中确实不存在引用传递,只有值与地址值传递,而如何去理解,只要你java基础知识扎实,值传递看起来一切都是那么自然。

1.基本数据类型

对于基本数据类型一般我们会引用一段特别经典的代码:

public class Demo01 {
	//基本类型参数的传递过程
	public static void main(String[] args) {
		int x = 3;
		show(x);
		System.out.println(x);
	}
	public static void show(int x) {
//被省略的传参过程:x = x(3);
		x = 4;
//		return;
	}
}

输出x的值为3,为什么不是4?

注意:当我们调用方法传实参x时,Java语法会帮我们省略一段代码,就是将实参x赋值给形参x的代码。

那为什么要省略呢?原因很简单:

我们封装方法时并不知道传入实参的变量名,赋值等式右边没法写。

但当我们把省略的这一行代码以自己理解的方式添加到注释中去,一切就明朗了。

那么这个show()方法就可以理解为,给方法中的形参x赋了两次值。

接下来我们用局部变量的知识去理解就足够了。

来看看局部变量的概念:

定义:在方法内定义的变量称为“局部变量”或“临时变量”,只在所属区域中有效,方法结束后局部变量占用的内存将被释放。

在main()方法中的定义的变量x就是一个作用域为整个主方法的局部变量,而在下面show()方法参数列表中定义了一个同名的变量x,这两个变量在各自的方法区中都是唯一的,互不相干。

那么接下来,打印main中局部变量x的值,纵使你show方法中的x被赋值一万次,也与他无关。

2.引用数据类型

public class Demo02 {
	//引用类型参数的传递过程
	int x ;
	public static void main(String[] args) {
		Demo02 d = new Demo02();
		d.x = 9;
		show(d);
		System.out.println(d.x);
	}
	public static void show(Demo02 d) {
		//省略的传参过程 d=d;
		d.x = 4;
	}
}

打印结果是4,那为什么这一次show中的局部变量能改变main方法中的局部变量的属性呢?

我们还是把省略的传参过程加上,很显然这一次我们传递进去的引用类型,对于引用类型,“=”的概念就是改变地址值指向。那么这个show()方法就可以理解为,将main方法中d的地址值提供给show中的局部变量d指向。现在,两个局部变量d共同指向一个地址,那不管哪一个都可以访问到此对象的属性,自然可以改变他。

我们再添一行代码

public class Demo02 {
	//引用类型参数的传递过程
	int x = 3;
	public static void main(String[] args) {
		Demo02 d = new Demo02();
		d.x = 9;
		show(d);
		System.out.println(d.x);
	}
	public static void show(Demo02 d) {
		//省略的传参过程 d=d;
		d=new Demo02();
		d.x = 4;
	}
}

输出结果为9,为什么这次又没变呢?

原因也很简单,传参时方法中的局部变量d指向了main方法中的Demo02对象地址,还没来得及修改这个对象的属性,就又被覆盖指向了一个新对象的地址值,那你再怎么改,也找不到回家的路了,那么main方法打印的自然是原来的属性。

看过这两个案例,我们再来看看String类的值传递:

public class Demo03 {
	public static void main(String[] args) {
		String str="111";
		change(str);
		System.out.println(str);
			}
	public static void change(String str) {
        //省略的传参过程 str=str("111");
		str="222";
	}
}

输出结果为111,String不是引用数据类型吗?怎么没改变呢?

原因在于String类的对象根本就不可变,任何你以为的改变str的方法其实都是提供新的地址值指向。那么就和上面一个例子一样,show方法中的局部变量str丢失了原来的地址。

上述这些案例,关于java值传递我们可以肯定的是:

①对于基本数据类型,不管方法内部如何变动,不能改变传递给形参的实参变量值。

②对于引用数据类型,不管方法内部如何变动,不能改变传递给形参的实参变量地址指向,但能改变指向对象的属性。

对于引用数据类型,笔者总结了一个通俗易懂的比喻:

实参和形参是两个好朋友,实参把他家的地址告诉形参,形参可以根据地址到实参家住甚至给实参家装修,但是有一天形参找到新家了,就算把新家全部翻新一遍,实参的家还是原来的家。

本文旨在给初学者简单快速的理解值传递的概念,所以没有引入java内存等较抽象的知识,如有错误欢迎指正。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值