Java方法中,值传递和地址传递一直让我很迷惑,最近认真看了看资料分析了一下,供大家参考。
01 首先看题目:
public class test {
public static void main(String[] args) {
String str1="abc";
char[]str2={'a','b','c'};
exChange1(str1,str2 );
System.out.println(str1);
System.out.println(new String(str2));
StringBuffer sb1=new StringBuffer("A");
StringBuffer sb2=new StringBuffer("B");
exChange2(sb1,sb2 );
System.out.println(sb1.toString());
System.out.println(sb2.toString());
}
private static void exChange2(StringBuffer sb01,StringBuffer sb02){
sb01=sb02;
sb01.append(sb02);
}
private static void exChange1(String str1,char[]str2){
str1="gbc";
str2[0]='g';
}
}
题目的答案
abc
gbc
A
BB
02 理解定义
值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法执行中形式参数值的改变不影响实际参数的值。
引用传递:也称为传地址。方法调用时,实际参数的引用(地址,而不是参数的值)被传递给方法中相对应的形式参数,在方法执行中,对形式参数的操作实际上就是对实际参数的操作,方法执行中形式参数值的改变将会影响实际参数的值。
a.传递值的数据类型:八种基本数据类型和String(这样理解可以,但是事实上String也是传递的地址,只是string对象和其他对象是不同的,string对象是不能被改变的,内容改变就会产生新对象。那么StringBuffer就可以了,但只是改变其内容。不能改变外部变量所指向的内存地址)。
b.传递地址值的数据类型:除String以外的所有复合数据类型,包括数组、类和接口
参考:https://blog.csdn.net/maoyeqiu/article/details/49250339
03 值传递实例
public class Test {
public static void change(int i, int j) {
int temp = i;
i = j;
j = temp;
}
public static void main(String[] args) {
int a = 3;
int b = 4;
change(a, b);
System.out.println("a=" + a);
System.out.println("b=" + b);
}
结果:
a=3
b=4
解释:值传递,在调用方法change(a,b)相当于省略了 i=a,j=b。在这一步之后,方法change里面对 i 和 j 的操作与a、b是无关的。
04 引用传递
public class Test {
public static void change(int[] arr2) {
arr2[0] = 6;
}
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
change(arr);
System.out.println(arr[0]);
}
结果: 6
解释: 地址传递。通过方法change,将 arr 的地址传递给了 arr2 ,在方法change里,改变了 arr[ 0 ]地址的指向,结果会影响到 arr
可以将“地址” 理解为一个盒子,change方法,让arr2有了权限去操作盒子,将盒子里的东西换了。
05 原题分析
string是值传递,所有方法 exchange1,对str1操作与最初定义的str1是无关的。str1的值不变,为abc;
数据是地址传递,更改了最初的str2[ 0 ]的地址所指向的值,str2[ 0 ]的值改变,g
String str1="abc";
char[]str2={'a','b','c'};
exChange1(str1,str2 );
-----------------
private static void exChange1(String str1,char[]str2){
str1="gbc";
str2[0]='g';
}
}
StringBuffer 是地址传递(只要不是八大基本数据类型和string,其他都是地址传递)。
01)首先,方法 exChange2,将最初的sb1的地址传给了方法里的sb01,sb2的地址给了sb02;
02) 然后,sb01=sb02 : 将sb02的地址给了sb01(也就是说,这个时候,sb01和sb02的地址是一样的,都是sb2的了),值都为“B”;
03)sb01.append(sb02),操作的实际对象是sb2的地址,所以与sb1无关。sb1的值不变
, sb2的值发生改变
StringBuffer sb1=new StringBuffer("A");
StringBuffer sb2=new StringBuffer("B");
exChange2(sb1,sb2 );
System.out.println(sb1.toString());
System.out.println(sb2.toString());
}
private static void exChange2(StringBuffer sb01,StringBuffer sb02){
sb01=sb02;
sb01.append(sb02);
}
}
这个代码运行结果为:
abc
gbc
A
BB