在这之前我们必须先搞懂数据类型、形式参数和实际参数
1.数据类型什么是数据类型,数据类型有哪几种,大家可以观看一下这篇文章Java之数据类型解析
2.形参与实参形参:全称形式参数,是定义函数时在括号里定义的变量,它只是申明用的,是没有值的。
实参:全称实际参数,是调用函数时传给形参的值,是有值的。实参是形参被具体赋值之后的值,参加实际的运算,有实际作用。
下面通过一段代码来看看形参与实参
public class Test {
public static void func(int x) {//x为形参
}
public static void main(String []args) {
int a = 10;//实参
func(10);
}
}
搞懂了这些下面我们正式进入主题
3.值传递与引用传递值传递:值传递是指在调用函数时将实际参数复制一份副本传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递:所谓引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
值得一提的是Java中只有值传递
public static void func(int x) {//x为形参
x = 20;
System.out.println("在函数中该值为"+x);
}
public static void main(String []args) {
int a = 10;//实参
func(10);
System.out.println("调用后该值为"+a);
}
通过运行结果可以看到,在方法调用时参数值为20,调用完后还是原来的值,函数中x的值是拷贝实参a的一个副本,不是真正a的值 ,说得通俗一点,就是你有一本学习资料,你们室友看到后就借去复印,由于他疯狂的内卷,他那本学习资料写满了内容,而你的那本还是空白的,这就是值传递。
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class Test {
public static void func(Student s) {
s.setName("王一");
s.setAge(22);
}
public static void main(String []args) {
Student s = new Student("牛二",18);
System.out.println("参数调用前"+s);
func(s);
System.out.println("参数调用后"+s);
}
}
上文我们说过Java中只有值传递,这里把他改了,是怎么回事呢?
这里的i也是值传递,只不过这个i拷贝的是一个地址不是一个具体的值
我们在来看看String
public static void func(String str) {
str = "王一";
}
public static void main(String []args) {
String s = new String("牛二");
func(s);
System.out.println(s);
}
为什么这里的值又没有变呢?
因为String、integer是不可变的类
总结:当参数是类(除了不可变的类以外)这种引用数据类型时,修改其属性,原有的值也会发生改变,原因是形参拷贝了实参的地址作为副本,他们两共用一个地址。



