详解java参数传递中值传递与引用传递

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44936331/article/details/99695792


言简意赅的介绍java中值传递与参数传递

1.值传递与引用传递的定义

值传递:
方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相等的基本类型,即实际参数和形式参数,后面方法中的操作都是对形参这个值的修改,不影响实际参数的值。

引用传递:
也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,函数接收的是原始值的内存地址;在方法执行中,形参和实参内容相同,指向同一块内存地址,方法执行中对引用的操作将会影响到实际对象。

1.基本类型作为参数传递

1.1基本类型作为参数传递时,是传递值的拷贝,无论你怎么改变这个拷贝,原值是不会改变的

/**
 * @author wang7
 *测试java中值的传递
 */
public class ValueTest {
	public static void main(String[] args) {
		 int a = 1;

	     System.out.println("Before a = " + a);

	     changeData(a);

	     System.out.println("After change a = " + a);
	}
	//测试基本数据类型变为参数传递时值的变化
	private static void changeData(int a) {
		// TODO Auto-generated method stub
		a = 10;
	}
}
//输出结果:
//Before a = 1
//After change a = 1
1.2堆栈信息

这种类型如int=3的形式来定义,称为自动变量。自动变量存在的是字面值,即不是类的实例,也不是类的引用。a 是一个指向int类型的引用,指向3这个字面值。这些字面值的数据由于大小可知,生存期可知(这些字面值固定定义在某个程序块里面,程序块退了,字段值就消失了),处于追求速度的原因就存在栈中。

2.对象作为参数传递

2.1.对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。
/**
 * @author wang7
 *参数为引用类型时值的传递
 */
public class ValueTest {
	 public static void main(String[] args) {

	    StringBuffer sb = new StringBuffer("Hello ");

	    System.out.println("Before sb = " + sb);

	    changeData(sb);

	    System.out.println("After sb = " + sb);

	}

	   public static void changeData(StringBuffer strBuf) {

	   strBuf.append("World!");

	   }
}
//输出结果:
//Before sb = Hello 
//After sb = Hello World!

2.2堆栈信息:

未执行 strBuf.append(“World!”);的堆栈中的信息,现在这种情况下引用变量作为参数传递时传递的是地址

在Java中对象作为参数传递时,是把对象在内存中的地址拷贝了一份传给了参数。
/**
 * @author wang7
 *参数为引用类型时值的传递
 */
public class ValueTest {
	public static void main(String[] args) {

        StringBuffer sb = new StringBuffer("Hello ");

        System.out.println("Before sb = " + sb);

        changeData(sb);

        System.out.println("After sb = " + sb);

    }     

       public static void changeData(StringBuffer strBuf) {

           strBuf = new StringBuffer("HHH ");

           strBuf.append("World!");

    }

}
堆栈信息

在这里插入图片描述

3.特别注意final修饰的类

这里要特殊考虑String,以及Integer、Double等基本类型包装类,它们的类前面都有final修饰,为不可变的类对象,每次操作(new或修改值)都是新生成一个对象,对形参的修改时,实参不受影响,与值传递的效果类似,但实际上仍是引用传递。

总结:

1)基本类型变量作为方法中的参数,进行的值传递,对形参的修改不影响实参的原来的值;
2)非final修饰的类、数组、接口作为方法中的参数,进行的传递,对形参修改后实参也会改变,因为二者指向的是同一个实例;
3)final修饰的类作为方法中的参数,因为final的存在初始化后值不可变,每次操作都相当于产生一个新的实例对象,因此对形参修改时,实参也不受影响。

猜你喜欢

转载自blog.csdn.net/weixin_44936331/article/details/99695792