值传递与引用传递
摘抄自威哥视频
例一:值传递(说白了,就是内容复制,或者说内容的副本)
public class ValueDemo{ public static void main(String[] args){ int x = 10; method(x); System.out.println("x="+x); } public static void method(int mx){ mx = 20; } }
例二:下面三个都是引用传递
package sunjava; public class RefDemo2{ public static void main(String[] args){ String name = "小白"; method(name); System.out.println("name="+name); } public static void method(String sname){ sname = "小红"; } }
name=小白
例三:引用传递(说白了,就是地址传递,指向了同一个地址。栈内寸两个变量存储的是同一个地址。)
package sunjava; public class RefDemo1{ public static void main(String[] args){ Cat c = new Cat(); method(c); System.out.println("Cat age = "+c.age); } public static void method(Cat cat){ cat.age = 5; } } class Cat{ int age = 2;//省略封装 }
5
例四:字符串特例
package sunjava; public class RefDemo3{ public static void main(String[] args){ Cat c = new Cat(); method(c) ; System.out.println("Cat name= "+c.name) ; } public static void method(Cat cat){ cat.name = "小黑"; } } class Cat{ String name = "小白"; //省略封装 }
Cat name= 小黑
总结:
1、每次new一个对象,就是在堆内存当中开辟一个新的空间。【无论以前是否有重复,如string1=new String(“helloworld”),如例五的string2和string4是false】
2、例四的 String name = "小白"; 字符串也是一个新的对象。
3、一个字符串就是一个对象
例六:==(比较地址,就是指针的地址)与euals(比较内容,就是指针指向的内容)
public class String_test { public static void main(String[] args) { String str1 = "hello world"; String str2 = new String("hello world"); String str3 = "hello world"; String str4 = new String("hello world"); System.out.println(str1==str2); System.out.println(str1==str3); System.out.println(str2==str4); System.out.println(str2.equals(str4));//上面是地址,所以false,这里是内容 true /* 上面的结果为 * --------------- * false true false true*/ // 1. 下面这段代码的输出结果是什么? String a = "hello2"; String b = "hello" + 2; System.out.println((a == b)); // 输出结果为:true。原因很简单,"hello"+2在编译期间就已经被优化成"hello2",因此在运行期间,变量a和变量b指向的是同一个对象。 // 2.下面这段代码的输出结果是什么? String a2 = "hello2"; String b2 = "hello"; String c2 = b2 + 2; System.out.println((a2 == c2)); // 输出结果为:false。由于有符号引用的存在,所以 String c = b + 2;不会在编译期间被优化,不会把b+2当做字面常量来处理的,因此这种方式生成的对象事实上是保存在堆上的。因此a和c指向的并不是同一个对象 } }
例七:一个字符串就是一个对象。如果没有找到相同的,就新建一个对象,指向原来的内容一把x,指向新的。
public class sadf { public static void changeStr(String str) { str="welcome"; System.out.println(str); } public static void main(String[] args) { String str="1234"; changeStr(str); System.out.println(str); } } /* * 结果为 *----------------* * welcome 1234 */
例八:
public class sdf { public static void main(String[] args) { String str=new String("world"); char ch[]={'H','e','l','l','o'}; change(str,ch); System.out.println(str+"and"); System.out.println(ch); } public static void change(String str,char ch[])//数组的本质传递的是地址 { str="Change";//这个上面的例题同 ch[0]='c'; } } /* * 结果为 *----------------* worldand cello */
从上面这个例子我们知道,字符串是值传递,而数组是句柄传递(c++,也就是指针)
c++的竟然也是一样的结果
#include <iostream> using namespace std; void Change(char *str2,char *ch) { str2="Change"; ch[0]='C'; } int main() { char *str2="world"; char ch[]={'H','e','l','l','o'}; Change(str2,ch); cout <<str2; cout << "and" <<endl; cout << ch << endl; return 0; }
c++灵活的地方在于字符串中可以传地址(强制传入地址) 而java 和c#确不可以做到这一点,而只能用返回值的方法来实现。
如下,修改版的就可以
#include <iostream> using namespace std; void Change(char **str2,char *ch) { *str2="Change"; ch[0]='C'; } int main() { char *str2="world"; char ch[]={'H','e','l','l','o'}; Change(&str2,ch); cout <<str2; cout << "and" <<endl; cout << ch <<endl; return 0; }
参考文章:http://www.cnblogs.com/bluewelkin/p/4080767.html
例9:
public class sdf { public static void main(String[] args) { String str=new String("world"); char ch[]={'H','e','l','l','o'}; change(str,ch); System.out.println(str+"and"); System.out.println(ch); } public static void change(String str,char ch[])//数组的本质传递的是地址 { str="Change";//这个上面的例题同 // / ch[0]='c'; ch=new char[]{'c','e','l','l','0'}; //相当于新备了一把钥匙,新建了一个仓库,但没有改变原来的值。 } } /* * 结果为 *----------------* worldand Hello */
例十:
public class asdf{ public static void main(String[] args){ String foo="blue"; String bar=foo; foo="green"; System.out.println(bar); System.out.println(foo); } } /*结果为: blue green*/
例十一:
public class asdf{ public static void main(String[] args){ String a = "ABCD"; String b = a.toLowerCase(); String c= b.replace('a', 'd');//这样替换新建一个才有效 b.replace('b','c');// 这样替换还是原来的 System.out.println(b); System.out.println(c); } } /*结果为: abcd dbcd */