数据类型
Java中的数据类可以分为两类:基本类型和引用类型。
基本类型包括整型(byte,short,int,long)、浮点型(float,double)、字符型(char)、布尔型(boolean)。
引用类型包括类、接口、数组。
很多介绍Java的文章都会说,Java方法有两种传参方式:值传递和引用传递。
真的有两种传参方式吗?
我们先来看下基本类型和引用类型在内存中是如何存储的。
基本类型
基本类型变量在内存中会直接存储变量的值,比如:int a = 1;
那么a对应的内存单元中存储的就是1。
(图片来源:王争《Java编程之美》https://www.xzgedu.com/detail/p_625cfab5e4b01a4851f30d8a/6)
引用类型
引用类型变量存的不是对象本身,而是对象所在内存块的首地址。
Student stu = new Student(1,3);
stu作为引用类型的变量,存的是Student对象在内存中的首地址。
(图片来源:王争《Java编程之美》https://www.xzgedu.com/detail/p_625cfab5e4b01a4851f30d8a/6)
方法传参
如果方法的参数是基本类型,那么调用方法的时候,会把变量在内存中值复制给方法的参数,也就是change(a)方法会把,a在内存中的值1复制一份传给变量x。
因为x是方法change的局部变量,是存在change方法栈中的,并不会影响存在main方法栈中的a变量,所以输出结果是1。
public static void main(String[] args) {
int a = 1;
change(a);
System.out.println(a); // 输出结果为1
}
public static void change(int x) {
x = 2;
}
如果方法参数是引用类型,那么调用方法的时候,同样会把变量在内存中值复制给方法的参数,也就是change(stu)方法会把,stu在内存中的值,也就是Student对象的首地址,复制一份传给变量stux。
这样变量stu和变量stux在内存中的值都是一样的,都是Student对象的首地址,也就是说变量stu和变量stux的值指向了同一个Student对象。
所以在change方法中变量stux,修改了其所指向对象的属性age,也就是修改了变量stu所指向对象的属性age,因为它们指向的是同一个对象。
public static void main(String[] args) {
Student stu = new Student(1,20);
change(stu);
System.out.println(stu.age); // 输出结果为18
}
public static void change(Student stux) {
stux.age = 18;
}
static class Student {
int id;
int age;
public Student(int id,int age) {
this.id = id;
this.age = age;
}
}
总结
总结一下,不管方法的参数类型是基本类型还是引用类型,它们传递都是变量在内存中的值,只是基本类型在内存中的值就是值本身,引用类型在内存中存的是对象的首地址而已。
所以,在Java语言中方法传参,不管是基本类型还是引用类型都是按值传递的,都是传递变量中的值。
那C++为什么有引用传递呢?
因为C++可以通过"&"引用获取到一个变量的地址,它可以将变量的地址传给函数。
随便从网上找了一幅图说明一下:
C++的引用传递,传的是变量自己的地址:0x7fff5cc109de
Java传递的是变量里的值:10
(如果是引用类型的变量,那么变量里的值就是对象的首地址,不管怎么样,传的都是变量里的值)
所以说Java没有引用传递,只有值传递。