值传递和引用传递的概念和区别
参考回答:
值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量.
引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身。所以对引用对象进行操作会同时改变原对象.
一般认为java内的传递都是值传递.
分析:
这里首先要明白几个重要的概念:
- 基本类型和引用类型的区别
- “=”赋值运算的本质
1.基本类型和引用类型的区别:
int data = 20;
String str = "11111";
这里data是基本类型,20这个值是直接存在变量中的,但是str却是引用类型,事实上str存的是对象的地址,这种变量称为引用,指向的对象中保存着1111的值
2. “=”赋值运算的本质
int data = 20;
data = 21;
String str = "11111";
str = "22222";
这里的确是可以改变两个变量的值,看起来非常类似,其实不然,其中有着很大的区别。
data的值改变是直接将21覆盖了data 的值,但是str的改变其实是先创建了一个新的String对象,里面保存着2222的值,之后将str里的地址变成指向新对象的地址了,其实原先对象的内容并没有改变。
了解完这个之后我们来看例子:
public static class ArgumentPass {
public void dataChange(int d){
d += 1;
System.out.println("参数d的值是:"+d);
}
public void strChange(String s){
s += "22222";
System.out.println("参数s的值是:"+s);
}
}
public static void main(String[] args) {
ArgumentPass argumentPass = new ArgumentPass();
int data = 20;
argumentPass.dataChange(data);
System.out.println("data的值是:"+data);
String str = "11111";
argumentPass.strChange(str);
System.out.println("str的值是:"+str);
}
输出:
参数d的值是:21
data的值是:20
参数s的值是:1111122222
str的值是:11111
在这个例子里,我们可以看到,无论是传int,还是String,我们需要的值都没有改变,改变的都仅仅是形参的值,也就是说这就是值传递。这里有个问题就是,为什么第二个方法也是值传递呢?其实很简单就能理解,第二个方法内就是新建了一个String对象,将s里面的地址给覆盖了!
下面再看个一个很经典的例子:
//类内部方法
public void addAge(int age){
this.age++;
}
DataString dataString = new DataString("fanglei",20);
int age = dataString.getAge();
dataString.addAge(age);
System.out.println(age);
System.out.println(dataString.getAge());
输出:
20
21
这个例子是很经典,我们调用的是类内部的方法,所以肯定是可以改变age 的值的,但是要记住改变的是这个对象中的age,我们定义的age并没有改变。
再看两个例子:
public static void strChangeTo(StringBuffer str1){
str1.append("22222");
}
public static void strChangeTo1(StringBuffer str2){
str2 = new StringBuffer("lnisahdkjas");
}
StringBuffer strx = new StringBuffer("woshi");
strChangeTo(strx);
System.out.println("strx的值是:"+strx);
StringBuffer stry = new StringBuffer("woshi");
strChangeTo1(stry);
System.out.println("stry的值是:"+stry);
输出:
strx的值是:woshi22222
stry的值是:woshi
这两个例子,同样都是修改StringBuffer的值,但是一个调用的是内部的方法,一个是进行赋值,所以结果显而易见!
也就是说,要想进行引用传递,并不是看传数据类型的是什么,而是看调用的方法是什么样的!