今天书又看到了java的引用传递,想了下,在C/C++有值传递、指针传递、引用传递,但在java里面就只有引用传递了,其实我感觉在java里面引用传递就大致相当于指针,原理差不多,那下面通过几个例子来看下java的引用传递。
引用传递是整个java的精髓所在,所以了解这个东西是很有必要的。
示例One:
class Demo {
private int data = 10;
public Demo(int data) {
this.data = data;
}
public void setData(int data) {
this.data = data;
}
public int getData() {
return this.data;
}
}
public class TestDemo {
public static void main(String args[]) {
Demo demo = new Demo(100);
fun(demo); // 等价于:Demo temp = demo ;
System.out.println(demo.getData());
}
public static void fun(Demo temp) { // 接收引用
temp.setData(30); // 修改属性内容
}
}
Result:
30
代码中,main()方法中先实例化了一个对象Demo,同时为data赋值100,之后将对象传递给了fun()方法,由于类本身属于引用数据类型,所以在fun()方法中的修改直接会修改原始对象中的内容。
示例Two:
public class TestDemo {
public static void main(String args[]) {
String str = "Hello"; // 定义字符串
fun(str); // 引用传递:String temp = str ;
System.out.println(str);
}
public static void fun(String temp) {
temp = "World"; // 修改字符串内容
}
}
Result:
Hello
咦?咋没变呢。。。
这个地方要注意了,代码中使用了String类做为引用的数据类型,这里要了解的是String的内容一旦声明则不可改变,改变的是内存地址的指向。所以在修改字符串数据(temp = “World”)时就发生了引用地址的变更,此时会在堆空间中生成一个“World”,而是把“World”的地址赋值给了temp,但之前的str指向的地址却没有发生变更。因此就出现了上述结果。
对于像Strng、int等基本数据类型,要注意这些情况。
示例Three:
class Demo {
private String data;
public Demo(String data) {
this.data = data;
}
public void setData(String data) {
this.data = data;
}
public String getData() {
return this.data;
}
}
public class TestDemo {
public static void main(String args[]) {
Demo demo = new Demo("Hello"); // 实例化对象
fun(demo); // 引用传递:Demo temp = demo ;
System.out.println(demo.getData());
}
public static void fun(Demo temp) {
temp.setData("World");
}
}
Result:
World
本例中有用到了String数据类型,这里我们要理解的是其对应的内存关系:Demo是String的引用,存放在栈中,而data又是字符串的引用也要存放于栈中,字符串在堆中,在Demo堆内存中保存了data对字符串的引用关系,这个理清楚了,也就明白怎么回事了。
关于Java引用传递先说这么多。
A little more for everyday.