【前方注意】:java中只存在值传递,值传递,值传递!!!
一、值传递(一切传引用其实本质上是传值)
总所周知,java没有指针的概念,但实际工作中经常看到对于对象(类、数组、接口)的传递似乎有点像引用传递,可以改变对象中的某个属性的值。但是不要被这个假象所蒙蔽,Java中所说的按引用传递实质上是传递该对象的地址,该地址其实是按值传递的,通过这个地址可以修改其指向内存处对象的值。改变该地址的值毫无意义,只会失去对真实对象的掌控。
二、什么是基本类型、引用类型
int num = 8;
String str = "hello";

如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为"引用",引用指向实际对象,实际对象中保存着内容。
三、赋值运算符(=)
num = 20;
str = "java";

对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。对于引用类型 str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。如上图所示,"hello" 字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)
四、调用方法时,参数传递基本上就是赋值操作
第一个例子:基本类型
void foo(int value) {
value = 100;
}
foo(num); // num 没有被改变
第二个例子:没有提供改变自身方法的引用类型
void foo(String text) {
text = "windows";
}
foo(str); // str 也没有被改变
第三个例子:提供了改变自身方法的引用类型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder.append("4");
}
foo(sb); // sb 被改变了,变成了"iphone4"。
第四个例子:提供了改变自身方法的引用类型,但是不使用,而是使用赋值运算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
foo(sb); // sb 没有被改变,还是 "iphone"。
图解例三:


图解例四:


网友评论