目录
总体代码
package test.t05new;
import java.util.ArrayList;
import java.util.Arrays;
public class Test9 {
public static void main(String[] args){
//test String
String str = "value";
TestClass tc = new TestClass();
System.out.println("str before is "+str+" ,memory address is "+System.identityHashCode(str));
tc.ChangeVlaue(str);
System.out.println("str now is "+str+" ,memory address is "+System.identityHashCode(str));
System.out.println("--------------------------------------");
//test int
int num = 0;
System.out.println("num before is "+num+" ,memory address is "+System.identityHashCode(num));
tc.ChangeVlaue(num);
System.out.println("num now is "+num+" ,memory address is "+System.identityHashCode(num));
System.out.println("--------------------------------------");
//test objectclass
TestClass testClass = new TestClass();
System.out.println("testClass before is "+testClass+";num: "+testClass.num+" ,memory address is "+System.identityHashCode(testClass));
tc.ChangeVlaue(testClass);
System.out.println("testClass now is "+testClass+";num: "+testClass.num+" ,memory address is "+System.identityHashCode(testClass));
System.out.println("--------------------------------------");
//test ArrryList
ArrayList<String> liststr = new ArrayList<String>();
liststr.add("str1");
System.out.println("liststr before is "+liststr+" ,memory address is "+System.identityHashCode(liststr));
tc.ChangeVlaue(liststr);
System.out.println("liststr now is "+liststr+" ,memory address is "+System.identityHashCode(liststr));
System.out.println("--------------------------------------");
//test Arrry
int[] intArray = new int[3];
intArray[0]=1;
System.out.println("liststr before is "+Arrays.toString(intArray)+" ,memory address is "+System.identityHashCode(intArray));
tc.ChangeVlaue(intArray);
System.out.println("liststr now is "+Arrays.toString(intArray)+" ,memory address is "+System.identityHashCode(intArray));
}
}
class TestClass{
public TestClass(){
System.out.println("TestClass constructor ");
}
int num = 0;
public void ChangeVlaue(String str){
str = "changed value";
}
public void ChangeVlaue(int num){
num ++;
}
public void ChangeVlaue(TestClass testClass){
testClass.num ++;
testClass = new TestClass();
testClass.num ++;
}
public void ChangeVlaue(ArrayList<String> liststr) {
liststr.add("str2");
liststr = new ArrayList<>();
liststr.add("str3");
}
public void ChangeVlaue(int[] intArray) {
intArray[1] = 2;
intArray = new int[3];
intArray[2]=3;
}
}
返回结果
TestClass constructor
str before is value ,memory address is 366712642
str now is value ,memory address is 366712642
--------------------------------------
num before is 0 ,memory address is 1829164700
num now is 0 ,memory address is 1829164700
--------------------------------------
TestClass constructor
testClass before is test.t05new.TestClass@7852e922;num: 0 ,memory address is 2018699554
TestClass constructor
testClass now is test.t05new.TestClass@7852e922;num: 1 ,memory address is 2018699554
--------------------------------------
liststr before is [str1] ,memory address is 1311053135
liststr now is [str1, str2] ,memory address is 1311053135
--------------------------------------
liststr before is [1, 0, 0] ,memory address is 118352462
liststr now is [1, 2, 0] ,memory address is 118352462
传递机制
形参是基本数据类型
传递数据值
实参是引用数据类型
传递地址值
特殊的类型:String、包装类等对象不可变性
字符串与基本类型
可以看到,这种情况,传递的方法参数的修改,对调用方无影响
注意:对于Integer等包装类,传递的方法参数的修改,对调用方无影响!
对象,容器类,数组
可以看到,这种情况,内存的地址没有变,也就是还是同一个对象,但是三者的内容变了
总结
Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本(也就是对象的一个地址)。
指向同一个对象,对象的内容可以在被调用的方法中改变(根据地址,到目的地进行修改),但对象的引用(不是引用的副本)是永远不会改变的(调用方的地址永远不会改变)。
Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。
如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的值不会改变原始的值.
如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。