上代码:
public class Demo { public static void main(String[] args) { test_1(); test_2(); } public static void test_1(){ String param=new String("aaa"); function(param); System.out.println(param); } public static void test_2(){ Instance ins=new Instance(); ins.setValue("111"); function(ins); System.out.println(ins.getValue()); } public static String function(String param){ param=new String("bbb"); return "ccc"; } public static String function(Instance ins){ ins.setValue("222"); ins=new Instance(); ins.setValue("444"); return "333"; } }
Instance类:
public class Instance { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } }
猜猜打印结果是啥。
aaa
222
解释:
java的基本数据类型是值传递,其他是引用传递
值传递的特点是:传递的是值的拷贝,也就是说传递后就互不相关了。
引用传递特点是:传递的是值的引用,也就是说传递前和传递后都指向同一个内存空间。
Instance是引用类型,是引用传递,传递的是内存空间,在function中被修改成222(h1)了;但是后面ins=new Instance()新开辟了一个内存空间(堆中的新元素h2),在子方法内指向了新开的这个内存地址,但是这个内存地址(或者说这个指针h2)并没有返回给主方法,所以一旦方法执行完毕,新开辟的这个地址(h2)就形成了孤岛(不被任何地方引用);方法外引用的还是原来那个地址(堆中的老元素)。
String虽然也是应用类型,但是是不可变量。所以是 aaa.
在jvm中,堆存放引用对象的地址,栈存放对象的引用和基本数据类型。
下面再看一个例子:
public class Demo { public static void main(String[] args) { test_1(); test_2(); } public static void test_1(){ String param=new String("aaa"); function(param); System.out.println(param); } public static void test_2(){ Instance ins=new Instance(); ins.setValue("111"); ins=function(ins);//此处接收返回值,相当于把子方法内的ins新指针(h2)返给了主方法内的变量 System.out.println(ins.getValue()); } public static String function(String param){ param=new String("bbb"); return "ccc"; } public static Instance function(Instance ins){ ins.setValue("222"); ins=new Instance(); ins.setValue("444"); return ins; } }
此时打印结果为:
aaa
444
补充:
以下代码打印为:
222 111 111
public class Demo { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public String fun(Demo b, int i, String str) { b.setName("222"); i = 222; str = "222"; return str; } public static void main(String[] args) { Demo demo = new Demo(); demo.setName("111"); int i = 111; String str = "111"; demo.fun(demo, i, str); System.out.println(demo.getName()); System.out.println(i); System.out.println(str); } }