在Java中都是值传递的
基本数据类型
在调用方法时,都是将变量的值传递给形参,而后对形参进行操作,而不是对该变量的值进行操作
例如:
class Hello{
public static void main(String[] args){
int num = 1;
add(num); //这里输出num值为2
System.out.println(num); //这里输出num值为1
//在方法add中虽然参数名与主函数中定义的变量名一样,但是是在不同栈帧中的不同变量,一个变量的值的改变并不会影响另一个变量的值。
}
public static void add(int num){
num++;
System.out.println(num);
}
}
学过指针就容易理解,在 Java中就相当于没有使用指针,因而方法中的参数与传入的参数是两个地址,一个值的改变不会影响另一个值
引用数据类型
在之前**[Java]面向对象概念**博文中提到过,引用数据类型实际上存储的值为该对象在堆中的地址,所以与基础数据类型不同,调用方法是若是参数为引用数据类型,在方法体内操作数据,实质上操作的是堆中该对象的属性,因此会同步引起该数据类型的改变
例如:
class Hello{
public static void main(String[] args){
Student student = new Student("张三", 1);
changeName(student);
System.out.println(student.name); //此时打印的值为 李四
}
public static void changeName(Student student){
student.name = "李四";
}
}
class Student{
String name;
int num;
public Student(String name, int num){
this.name = name;
this.num = num;
}
}
但是并不是说java这里就是引用传递,在本文中第一句都提过 java永远都是值传递。但是这里传递的值是堆中对象的地址,才能够引起外部变量的同步改变。
因此,引用数据类型并不是在所有场合下都会跟上面示例一样,会发生方法内变量改变影响方法外变量的情况
例如:
class Hello{
public static void main(String[] args){
Student student = new Student("张三", 1);
changeName(student);
System.out.println(student.name); //此时打印的值仍为 张三
}
public static void changeName(Student student){
student = new Student("李四", 2);
}
}
class Student{
String name;
int num;
public Student(String name, int num){
this.name = name;
this.num = num;
}
}
上面代码唯一一处改变就是changeName函数中虽然接收了外部参数student(外),但在方法体内又为student(内)重新new了一个对象,此时在堆中也新开辟了一块空间来管理该对象的属性信息,地址当然也与之前不同,student(内)存储的地址也指向了该地址,而student(外)存储的地址仍然指向原先的对象,因此,两个student此时已经没有了联系,指向了两个不同的对象,故修改student(内)的属性信息并不会影响到student(外)的属性信息
String等常量池有关数据类型
这种情况其实与引用数据类型中的第二种情况相似,都是内部变量的改变并不影响外部变量的改变
例如:
class Hello{
public static void main(String[] args){
String str = "张三";
changeString(str);
System.out.println(str); //此时打印的值仍为 张三
}
public static void changeString(String str){
str = "李四";
}
}
首先在main函数中定义str(外)时,就在常量池内开辟了一个空间用于存储“张三”,此时str(外)的值为该空间的地址。在调用changeString函数时,执行 str = “李四” 语句之前,str(内)与str(外)的值是相同的,都是指向常量池内值为“张三”的空间的地址。而在执行该语句时,程序在常量池内又开辟了一块空间用来存储“李四”,此时str(内)的值变更为常量池内“李四”的地址,而str(外)的值仍然为“张三”的地址,此时两个str也已经没有了联系,故打印出来的值还是“张三”。