引用传递
所谓的引用传递就是指将堆内存空间的使用权交给多个栈空间。下面有三个范例:
范例一:
对象引用传递
class Demo{
int temp = 50; //定义了一个整型的temp属性
}
public class Frist {
public static void main(String[] args) {
Demo d1=new Demo(); //实例化一个对象d1
System.out.println("未改变temp的值"+d1.temp);
d1.temp=500; //改变temp的值
System.out.println("fun()方法调用之前"+d1.temp);
fun(d1); //调用fun()方法,改变了temp的值
System.out.println("fun()方法调用之后"+d1.temp);
}
public static void fun(Demo d2) { //定义一个静态方法,由主方法直接调用
//一个类中,非static声明的方法可以调用static声明的属性或方法.但是static声明的方法是不能调用非static类型声明的属性或方法的
d2.temp = 70;//fun()方法改变了temp的值
}
}
运行结果:
未改变temp的值50
fun()方法调用之前500
fun()方法调用之后70
栈内存 | 堆内存 |
d1 | temp=30 |
(a)Demo d1=new Demo();
声明了一个对象d1,此时d1指向temp
栈内存 | 堆内存 |
d1 | temp=500 |
(b)d1.temp=500;
修改对象属性中的内容
栈内存 | 堆内存 |
d1 | temp=500 |
d2 |
(c)fun(d1);
调用fun方法,传递对象,此时d1和d2都指向temp
栈内存 | 堆内存 |
d1 | temp=70 |
d2 |
(d)fun()方法执行完后断开连接;
fun方法执行完毕,d2与temp建立连接之后又断开连接
范例二:
引用传递
public class Frist {
public static void main(String[] args) {
String str1 = "hello"; //实例化字符串对象
System.out.println("调用fun()方法之前,str1的值为:"+str1);
fun(str1); //调用fun()方法
System.out.println("调用fun()方法之后,str1的值为:"+str1);
}
public static void fun(String str2) { //此处的方法由主方法直接调用
str2="world"; //修改字符串内容
}
}
运行结果:
调用fun()方法之前,str1的值为:hello
调用fun()方法之后,str1的值为:hello
每一个字符串对象都表示一个匿名对象,这样在fun方法的操作中,如果为str2重新设置内容,就相当于改变了str2的引用,而str1不会受任何影响。
图片传递内容仅供参考,重点掌握传递方法
范例三:
引用传递
class Demo{
String temp = "happy";
}
public class Frist {
public static void main(String[] args) {
Demo d1 = new Demo();
System.out.println("d1原来的值为:"+d1.temp);
d1.temp="hello"; //修改对象中的temp属性
System.out.println("调用fun()方法之前,str1的值为:"+d1.temp);
fun(d1); //调用fun()方法
System.out.println("调用fun()方法之后,str1的值为:"+d1.temp);
}
public static void fun(Demo d2) { //此处的方法由主方法直接调用
d2.temp="world"; //修改属性内容
}
}
运行结果:
d1原来的值为:happy
调用fun()方法之前,str1的值为:hello
调用fun()方法之后,str1的值为:world
图片传递内容仅供参考,重点掌握传递方法
接受本类的引用
class Demo{
private int temp = 50; //定义了一个整型的temp属性,并进行封装
public void fun(Demo d2) { //构造了一个fun()方法
d2.temp=100; //将temp的值改为100
}
public int getTemp() { //getter方法用来返回temp的值
return temp;
}
public void setTemp(int temp) { //setter方法用来返回temp的值
this.temp = temp;
}
}
public class Frist {
public static void main(String[] args) {
Demo d1=new Demo(); //实例化一个对象d1
System.out.println("未改变temp的值"+d1.getTemp());
d1.setTemp(500); //使用setter方法对封装过的temp的值进行修改
System.out.println("fun()方法调用之前"+d1.getTemp()); //使用getter方法返回temp的值
d1.fun(d1); //此处把Demo的对象传回到自己的类中
System.out.println("fun()方法调用之后"+d1.getTemp()); //调用fun()方法,fun()方法将temp的值进行了修改。
}
}
运行结果:
未改变temp的值50
fun()方法调用之前500
fun()方法调用之后100
本例中注释部分表述不准确,因为字符串的内容一旦声明是不可以改变的,改变的只是内存地址。一个String对象内容的改变实际上是通过内存地址的断开—连接变化完成的,而本身字符串中的内容并没有任何的变化。