Java中只有值传递,没有引用传递!
很多小伙伴在学习java时,一直对其中的值传递与引用传递抱有疑惑。查阅资料后发现,java中本来就不存在引用传递,今天整理一下,供大家学习参考。
java两种数据类型:
- .基本类型:Java内置的八种基本的数据类型
基本类型存储在栈上,即实际对象就在栈上。 - 引用类型:Java内存放实际内容地址值的的一种数据形式(类、接口、数组)
引用类型也存储在栈上,不过存储内容为地址值,该地址值指向堆中,即实际对象存储在堆中。
实参与形参:
- 实参:赋值完成的变量。即方法被调用之前就已经被初始化,并在方法被调用时传入的参数。
- 形参:方法被调用时需要传递进来的参数。它只有在方法被调用期间才有意义,会被分配内存空间,在方法执行完成后,就会被销毁释放空间。
值传递与引用传递:
-
值传递:在方法被调用时,将实参复制一份传递给相应的形参(即c语言中变量的值),此时形参接收到的内容是实参值的一个拷贝,因此在方法内对形参的任何操作,都仅仅是对这个副本的操作,不影响原始值的内容。
-
引用传递:在方法调用时,将实参的地址传递给相应的形参(即c语言中变量的地址),在方法体内,形参和实参指向通愉快内存地址,对形参的操作会影响的真实内容。
-
基本类型的值传递
package tips1;
public class test1 {
public static void main(String[] args) {
int a=1;
changeTo(a);//实参,基本数据类型。
System.out.println(a);//调用函数后的a
}
private static void changeTo(int x){//形参
System.out.println(x);//改变前的形参
x=12;
System.out.println(x);//改变后的形参
}
}
打印结果:
1
12
1
当调用方法时,x接收a的拷贝值,并在栈上开辟空间。当改变x值时,并不会影响到a的变化,而当方法执行完时,x会被销毁,并释放内存。
- 引用类型的值传递:
public class test2 {
public static void main(String[] args) {
Person person = new Person();
person.setAge(17);
change(person);
System.out.println( person.getAge());
}
private static void change(Person value) {
//value=new Person();添加此行
value.setAge(18);
System.out.println(value.getAge());
}
private static class Person {
private Integer age;
private Integer getAge() {
return age;
}
private void setAge(Integer age) {
this.age = age;
}
}
}
打印结果:
18
18
大家可能会好奇,为什么值传递会改变实参的值?
其实大家认真理解值传递,引用传递以及引用数据类型的概念及其之间的区别与联系时,就很好理解了。
此处,形参虽然传递的是实参的拷贝值,但由于是引用类型,因此是实参与形参中存放的都是地址,且指向同一个地方。因此,当形参发生改变时,实参会随着形参发生改变。如果大家还有些不能理解,那么之前代码中屏蔽的放开:
public class test2 {
public static void main(String[] args) {
Person person = new Person();
person.setAge(17);
change(person);
System.out.println( person.getAge());
}
private static void change(Person value) {
value=new Person();添加此行
value.setAge(18);
System.out.println(value.getAge());
}
private static class Person {
private Integer age;
private Integer getAge() {
return age;
}
private void setAge(Integer age) {
this.age = age;
}
}
}
打印结果:
18
17
上述代码中,虽然形参与之前相同,但由于当执行到new Person()之后,JVM在堆内开辟一块空间存储新对象,并且把person改成指向新对象的地址,而形参的改变并没有引起实参的变化,便很好地说明了,java中没有引用传递,而该传递是值传递!
总结
Java中形参引起实参发生改变是由于传递类型为引用类型,Java中只有值传递!