Java中没有指针所以传参形式为值传递,即方法调用时,实际参数把它的值传递给对应的形式参数。
Java传参可以分为两种类型:
1)传递值的数据类型:八大基本数据类型
2)传递地址值的数据类型:引用数据类型
public class Demo {
public static void swp(int a) {
a+=2;
}
public static void main(String[] args) {
int a = 1;
System.out.println(a); //1
swp(a);
System.out.println(a); //1
}
}
a始终都是1,传递值不会改变原有的值。
class Money {
private double money;
public Money() {
}
public Money(double money) {
this.money = money;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public void addMoney(double money){
this.money = money+money*1.5;
}
}
public class Demo {
public static void add(Money money) {
money.addMoney(money.getMoney());
}
public static void main(String[] args) {
Money money = new Money();
money.setMoney(100);
System.out.println(money.getMoney()); //100.0
add(money);
System.out.println(money.getMoney()); //250.0
}
}
上面代码说明了引用数据类型传递的是栈中存放的地址,调用的函数处理的是原先的地址中的内容,所以money才会被修改。
但对于String 比较特别, String 是 final的。所以值是不变的。 函数中String对象引用的副本指向了另外一个新String对象,而数组对象引用的副本没有改变,而是改变对象中数据的内容。
public class Demo {
public static void change(String s) {
s = "down";
}
public static void main(String[] args) {
String str = new String("up");
System.out.println(str); //up
change(str);
System.out.println(str); //up
}
}
由于上面代码中的String是通过创建String对象指向常量池的,所以栈中会存放String对象的地址,当调用方法时,传递的是String对象的地址,进行修改时,因为String是不可被修改的,所以会在常量池中开辟新的空间(常量池中找不到对应数据时)存放新数据,再创建新的String对象指向新数据或直接指向常量池中的数据,而原本的str所指的对象没有改变,对象所指的常量池数据也没有改变,所以会出现上面的情况。
Java参数,不管是原始类型还是引用类型,传递的都是值。
如果参数类型是基本类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,如果在函数中改变了副本的值不会改变原始的值.
如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的地址,所以不会改变参数的值。