引用传递例子

引用传递是Java的精髓,核心意义在于:
同一块堆内存空间可以被不同的栈内存空间指向,不同栈内存可以对同一堆内存进行内容修改。


 目录

程序一 

程序二

程序三 

 总结


程序一 

class Message{
	 private int num=10;
	 public Message(int num) {
		 this.num=num;
	 }
	 public void setNum(int num) {
		 this.num=num;
	 }
	 public int getNum() {
		 return this.num;
	 }
 }


public class STATIC {
     public static void main(String[] args) {
         Message msg=new Message(30);
         fun(msg);//引用传递
         System.out.println(msg.getNum());   
     } 
     //外部函数fun()  加static原因是主函数是static,想调用外部函数也得static
     public static void fun(Message temp) {
    	 temp.setNum(100);
     }
	}



//程序结果:100

内存分析:

 首先通过Message类的构造函数给属性num赋值,然后在主程序中调用fun()方法,fun()方法的参数是Message类对象的引用,内存会为它开辟一个栈内存,然后和msg指向同一存储num值的堆内存
,然后fun()函数执行修改num值为100的操作,在执行结束后,断开连接。

程序二

public class STATIC {
     public static void main(String[] args) {
    	 String msg="hello world!";
         fun(msg);//引用传递
         System.out.println(msg);   
     } 
     //外部函数fun()
     public static void fun(String temp) {
    	 temp="no thank";
     }
	}



//运行结果:hello world!

内存分析:

 分析:堆内存遇见常数和“字符串”会开辟空间存储,执行fun(msg)时,先把temp指向msg的堆内存内容,然后在执行temp=“world”时,temp会断开原来的指向,转而建立新开辟的world内容的连接,所以fun()执行完毕后系统回收temp和无指向的world,导致msg指向内容没有改变。

public class STATIC {
     public static void main(String[] args) {
    	 int msg=10;
         fun(msg);
         System.out.println(msg);   
     } 
     //外部函数fun()
     public static void fun(int temp) {
    	 temp=100;
     }
	}

 同理:程序执行结果是:10;方法同String.
调用fun(msg)时候,temp指向了保存msg内容的堆内存,但是:执行:temp=100时,堆内存开辟空间存储100,temp断开了原来的指向,指向了新的100的内存空间。

程序三 

class Message{
	private String info="此内容无用";
	public Message(String info) {
		this.info=info;
	}
	public void setInfo(String info) {
		this.info=info;
	}
	public String getInfo() {
		return this.info;
	}
}
public class STATIC {
     public static void main(String[] args) {
    	 Message msg=new Message("hello");
         fun(msg);//引用传递
         System.out.println(msg.getInfo());   
     } 
     //外部函数fun()
     public static void fun(Message temp) {
    	 temp.setInfo("world");
     }
	}




//运行结果是:world  (fun()函数成功修改了info的内容)

内存分析:

  

       左上图:String也是一个类,所以在执行构造函数时:堆内存存放了info的对象,然后栈内存指向了该属性,对象存放在栈内存,然后该对象指向了堆内存存放的“hello”内容
      右上图:引用传递,temp指向了与msg相同的存储info对象的堆内存
      左下图:首先堆内存会先开辟存储“world”的空间,由于执行的是setinfo,是对象info调用的,所以指向从“hello”变为“world”,断开旧连接,指向新连接。
      右下图:执行完毕后,回收temp,hello没有指向,故而也会被回收。

 

 由于String类的内容是一旦复制后不可直接改变,一旦改变内容就会断开连接建立新连接,所以每一个String变量只可以保存一个内容。所以可以把String类视为基本类型(如:int),类比为直接在堆内存中赋值。

 总结

所谓引用传递就是调用外部函数达到修改属性内容的目的,难点就在于修改值的成功与否的分析。

class Book{
	private double price;
	public Book(double price) {
		this.price=price;
	}
	public void setPrice(double price) {
		this.price=price;
	}
	public double getPrice() {
		return this.price;
	}
}

public class transfer {
     public static void main(String[] args) {
		// TODO Auto-generated method stub
       Book a=new Book(99.9);
       fun(a);
       System.out.println(a.getPrice());
	}
    public static void fun(Book temp) {
    	temp.setPrice(199.88);
    }
}


运行结果:199.88

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值