java中是值传递还是引用传递?
结论:值传递
一、值传递、引用传递
先看一个例子:
在这个例子中函数private static void updata(int i)中的 i 就叫形参
updata(a)中的 a 就叫做实参
值传递:若改变了i的值,但是a的值不变,就是值传递
引用传递:若改变了i的值,a的值变了,那就是引用传递
public static void main(String[] args) {
int a=1;
System.out.println("刚赋值的a:"+a);
updata(a);
System.out.println("调用函数之后的a:"+a);
}
private static void updata(int i){
i++;
System.out.println("函数里面的a:"+i);
}
其输出结果为:
我们可以看到,函数里面的操作并没有影响到main方法中的a的值,那就是值传递吗?
我们再看一个例子 :
public static void main(String[] args) {
Student s1 = new Student("张三",16);
updata(s1);
System.out.println(s1);
}
private static void updata(Student student){
student.setName("李四");
}
诶?我们看到,这个例子中函数的修改导致了main方法中s1对象的值发生了变化,这难道是引用传递吗?我们往下分析。
二、传递机制
根据上面的第一个例子,我不做其他实验了,但是可以说的是JAVA中的八种基本数据类型肯定都是值传递,这一点是毋庸置疑的。那么JAVA中除了基本数据类型还有引用数据类型(类,接口,数组等等等一系列)。
基础知识我们都知道,在java内存中有栈和堆,我们创建一个基本数据类型的时候他是在栈中的,我们创建一个引用数据类型的时候他是在堆中的,
基本数据类型:我们传递的形参是一个副本
引用数据类型:我们的形参如果是一个引用数据类型,那么他传递的不是一个副本而是一个地址值:
- 传递的是对象的引用的值,即内存地址。
- 通过引用修改对象的属性会影响到原始对象。
public static void main(String[] args) {
Student s1 = new Student("张三",16);
updata(s1);
System.out.println(s1.getName());
System.out.println(s1);
}
private static void updata(Student student){
System.out.println(student);
student.setName("李四");
}
我们可以看到,地址是一模一样的。