java中的值传递还是引用传递?
1. 什么是值传递?
值传递是指在调用函数时将实际参数复制一份(副本)传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
public static void main(String[] args) {
int a = 1, b = 2;//实参
System.out.println("a: " + a);
System.out.println("b : " + b);
new IntTest().change(a, b);;
System.out.println("a: " + a);
System.out.println("b : " + b);
}
/**
*
* @author wangbo 2018年2月2日 上午11:55:12
*/
private void change(int a, int b) {
a = b;
System.out.println("change a = b; : " + a);
b = a +b;
System.out.println("change b = a +b : " + b);
}
a: 1
b : 2
change a = b; : 2
change b = a +b : 4
a: 1
b : 2
2. 什么是引用传递?
在C++中,函数参数的传递方式有引用传递。所谓引用传递是指在调用函数时将实际参数的引用(地址)传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数
3. 那么 java 中是值传递还是应用传递?
重要事情说三遍
java所有的参数传递都是传递的副本,变量所代表的值的副本!
java所有的参数传递都是传递的副本,变量所代表的值的副本!
java所有的参数传递都是传递的副本,变量所代表的值的副本!
接下来分别通过 java 基本类型 、 String、 StringBuffer 来进行验证说明
public static void main(String[] args) {
//定义实参 a、b
int a = 1, b = 2;
System.out.println("a : " + a);
System.out.println("b : " + b);
//将实参传递到 方法中进行操作
new IntTest().change(a, b);;
System.out.println("a : " + a);
System.out.println("b : " + b);
}
/**
*
* @author wangbo 2018年2月2日 上午11:55:12
*/
private void change(int a, int b) {
a = b;
System.out.println("change a = b : " + a);
b = a +b;
System.out.println("change b = a +b : " + b);
}
通上面的案例可以得到,java 的基本数据类型,是按值传递的,在方法 change 中,对形参 a、b 进行操作后,对调用者中的实参并未发生影响,调用者中的实参值并未发生改变
在java 中 String ,大家都知道 String 是一个对象,一个不可变的对象,对 String 操作,都会产生一个新的String对象,对原对象不会发生更改,那么在传递中,会是什么样呢??
public static void main(String[] args) {
String a = "hello ", b = "word";
System.out.println("a: " + a);
System.out.println("b : " + b);
new StringTest().change(a, b);;
System.out.println("a: " + a);
System.out.println("b : " + b);
}
/**
*
* @author wangbo 2018年2月2日 上午11:55:12
*/
private void change(String a, String b) {
a = b;
System.out.println("change a = b; : " + a);
b = a +b;
System.out.println("change b = a +b : " + b);
}
结果:
a: hello
b : word
change a = b; : word
change b = a +b : wordword
a: hello
b : word
如上面案例, 在方案 change 的 操作也没有导致 调用者中的实参发生任何改变。
public static void main(String[] args) {
StringBuffer a = new StringBuffer("hello"), b = new StringBuffer("word");
System.out.println("a: " + a);
System.out.println("b : " + b);
new StringBuffeTest().change(a, b);;
System.out.println("a: " + a);
System.out.println("b : " + b);
}
/**
* TODO 描述
* @author wangbo 2018年2月2日 上午11:55:12
*/
private void change(StringBuffer a, StringBuffer b) {
//这里改变了 a 的值,但上一层 中的a,并未被改变
a = b;
System.out.println("change a = b; : " + a);
//通过 b 引用改变 b 里面的值
b.append(a);
System.out.println("change b.append(a) : " + b);
}
结果:
a: hello
b : word
change a = b; : word
change b.append(a) : wordword
a: hello
b : wordword
如上案例,在 change 中对形参a操作,并未导致调用者中的实参发生变化;但对 b 的 “对象的值” 的操作导致了调用者中的实参也发生变化,请注意的是,这里操作的是形参 b 所代表的对象(类 StringBuffer 的实例)里面的值,并不是形参 b 的值;在 java 中对于对象类型变量保存的对象的引用,也就是形参 b 的值 和 实参 b 的值同时指向同一个对象当对形参b进行操作时,并不影响实参 b,但是如果对形参b所指向的对象里面的值进行操作时,会对实参b有影响的。
Java 语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该“对象的引用”一个副本。实参和形参指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
在 Java 中永远不会传递对象,而只传递对象引用。因此是按引用传递对象。但重要的是要区分参数是如何传递的,Java 按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数。参数可以是对象引用,而 Java 是按值传递对象引
用的。
Java 中的变量可以为以下两种类型之一:引用类型或基本类型。当作为参数传递给一个方法时,处理这两种类型的方式是相同的。 引用类型或基本类型 其实都是传递他们的一份副本,而不是数据本身。在 C++ 中当传递给函数的参数是引用时,您传递的就是这个引用,或者内存地址(按引用传递)。在 Java 中传递给方法的一个引用类型参数时,您传递的是该引用的一个副本(按值传递),而不是引用本身。
由于 java 中 引用类型保存值一个对象的引用,在传递中形参虽然实参的一个副本,但两者指向同一个对象,当对形参中的对象的值进行操作时,实参也会发生改变