Java教程
Java标识符与关键字
Java变量
Java数据类型
Java运算符
Java控制语句
Java方法
Java面向对象
Java对象的创建和使用
Java封装
Java中static和this
Java继承
Java方法覆盖和多态
Java super
Java基础练习题

Java方法调用时参数的传递问题

方法在调用的时候参数是如何传递的呢?其实在调用的时候参数传递给方法,这个过程就是赋值的过程,参数传递和“赋值规则”完全相同,只不过参数传递在代码上看不见“=”运算符。我们先来深入的研究一下“赋值规则”吧!

public class AssignmentTest {
	public static void main(String[] args) {
		//基本数据类型
		int a = 10;
		int b = a; //a赋值给b,a把什么给了b?
		//引用数据类型
		Bird bird1 = new Bird("polly");
        //bird1赋值给bird2,bird1把什么给了bird2?
		Bird bird2 = bird1; 
	}
}
class Bird {
	String name;
	public Bird(){}
	public Bird(String _name){
		name = _name;
	}
}

在以上程序当中,有两个疑问,第一个:a赋值给b,a把什么给了b?第二个:bird1赋值给bird2,bird1把什么给了bird2?

其实a,b,bird1,bird2就是4个普通的变量,唯一的区别只是a和b都是基本数据类型的变量,bird1和bird2都是引用数据类型的变量(或者说都是引用),a变量中保存的那个“值”是10,bird1变量中保存的那个“值”是0x8888(java对象内存地址),本质上来说10和0x8888都是“值”,只不过一个“值”是整数数字,另一个“值”是java对象的内存地址,大家不要把内存地址特殊化,它也是一个普通的值。

那么“赋值”是什么意思呢,顾名思义,赋值就是把“值”赋上去。a赋值给b,本质上不是把a给了b,而是把a变量中保存的“值10”复制了一份给了b。bird1赋值给bird2本质上不是把bird1给了bird2,而是把bird1变量中保存的“值0x8888”复制了一份给了bird2。请看以下内存图的变化:

Java技术架构

Java技术架构

图9-33:赋值原理图

通过以上内存图我们可以看出“赋值”运算的时候实际上和变量的数据类型无关,无论是基本数据类型还是引用数据类型,一律都是将变量中保存的“值”复制一份,然后将复制的这个“值”赋上去。他们的区别在于,如果是基本数据类型则和堆内存当中的对象无关,如果是引用数据类型由于传递的这个值是java对象的内存地址,所以会导致两个引用指向同一个堆内存中的java对象,通过任何一个引用去访问堆内存当中的对象,此对象内存都会受到影响。我们来验证一下,让a++,a应该变成了11,但是b不会变,让bird1.name = “波利”,然后输出bird2.name的结果肯定也是”波利”,请看代码以及运行结果:

public class AssignmentTest {
	public static void main(String[] args) {
		//基本数据类型
		int a = 10;
		int b = a; //a赋值给b,a把什么给了b?
		a++;
		System.out.println("a = " + a);
		System.out.println("b = " + b);
		//引用数据类型
		Bird bird1 = new Bird("polly");
        //bird1赋值给bird2,bird1把什么给了bird2?
		Bird bird2 = bird1; 
		System.out.println("bird1's name = " + bird1.name);
		System.out.println("bird2's name = " + bird2.name);
		bird1.name = "波利";
		System.out.println("bird1's name = " + bird1.name);
		System.out.println("bird2's name = " + bird2.name);
	}
}
class Bird {
	String name;
	public Bird(){}
	public Bird(String _name){
		name = _name;
	}
}

运行结果如下图所示:

Java开发

图9-34:赋值原理测试

上面我就提到了,方法调用时参数的传递和赋值运算符的原理完全相同,那么请大家根据以上内容所学,画出以下程序的内存图,以及推算它们的执行结果:

public class ParameterTransferTest01 {
	public static void main(String[] args) {
		int i = 10;
		add(i);
		System.out.println("main's i = " + i);
	}
	public static void add(int i){
		i++;
		System.out.println("add's i = " + i);
	}
}
public class ParameterTransferTest02 {
	public static void main(String[] args) {
		User user = new User(20);
		add(user);
		System.out.println("main's user age = " + user.age);
	}
	public static void add(User user) {
		user.age++;
		System.out.println("add's user age = " + user.age);
	}
}
class User{
	int age;
	public User(){}
	public User(int _age){
		age = _age;
	}
}

 

全部教程