值传递:方法接收的参数是原变量的值复制,在方法中参数值如何变化都不会影响到原变量。
值引用:方法接收的参数是原变量的堆/栈地址,在方法中,若参数的值被修改,原变量的值也会被修改。
1. 首先,Java中的变量有两种类型:基本类型、引用类型。
基本类型即:byte、short、int、long、float、double、char、boolean。所有的基本类型,都存储在栈内存中。
引用类型实际上是类对象,对于引用类型,对象存储在堆内存中,对象的引用地址(指针)存储在栈内存中。(数组对象、类对象)。
2. 在方法接收参数时,如果参数类型属于基本类型,那么传递的是【原变量值的拷贝】,参数值的变化不影响原变量值。即 值传递。 如果参数类型是数组或者类对象,那么传递的是【引用】,即传递的是该对象在栈中的引用地址。即 值引用。
3. String对象一旦被创建就不会被改变,对String对象的任何操作都不影响到原对象,任何change操作都会重新生成一个对象。
贴两个代码示例一下
public class A{
public static void main(String[] args){
int a = 123; //值传递
double d = 1.4286; //值传递
char[] chars = {'A','b','C','d','E'}; //值引用
String str = "Hello world"; //值引用,但每一次改变String的值都只会创建一个新的String对象
System.out.println("before="+a);
System.out.println("before="+d);
System.out.print("before=");
for(int i =0;i<chars.length;i++){
System.out.print(chars[i]+",");
}
System.out.println();
System.out.println("before="+str);
change(a,d,chars,str);
System.out.println("after="+a);
System.out.println("after="+d);
System.out.print("after=");
for(int i =0;i<chars.length;i++){
System.out.print(chars[i]+",");
}
System.out.println();
System.out.println("after="+str);
}
public static void change(int a,double d,char[] chars,String str){
a=0;
d = 3.1415;
chars[1] = 'V';chars[3]='Z';
str = "Fuck World";
}
}
class A{
private Integer id;
private String name;
public void setId(Integer id){ this.id = id; }
public Integer getId(){ return id; }
public void setName(String name){ this.name = name; }
public String getName(){ return name; }
public String toString(){ return "a.id="+this.id+"a.name="+this.name; }
}
public class B {
public static void main(String []args) {
A a = new A();
a.setId(12); a.setName("Jack");
System.out.println("Before: "+a.toString());
change(a);
System.out.println("After: "+a.toString());
}
public static void change(A a){// 值引用
a.setId(10); a.setName("Mary");
}
}