前言:引用傳遞是整個java的精髓所在,若是引用傳遞不清楚,那麼幾乎就等同於不會java,下面將經過三個程序進行引用傳遞的重複分析。 引用傳遞核心意義:同一塊堆內存空間能夠被不一樣的棧內存說指向,不一樣棧內存能夠對同一堆內存進行內容的修改。 PS:內容涉及String類,棧內存,堆內存相關知識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 ThisKeyWordDemo {
public static void main(String[] args) {
Message msg = new Message(30);
fun(msg);//引用傳遞
System.out.println(msg.getNum());
}
public static void fun(Message temp){
temp.setNum(100);
}
}
//輸出結果:100
複製代碼
fun(msg);將實例化的msg對象傳入的fun方法,也就是說temp就是指向msg方法,temp對象的操做等同於msg對象的操做。即:temp.setNum(100); 等價於 msg.setNum(100); 因此msg對象和temp對象操做的是同一塊棧內存,so,msg對象中的num值發生了改變。 咱們再來看第二個實例。bash
public class ThisKeyWordDemo {
public static void main(String[] args) {
String msg = "Hello ";
fun(msg);
System.out.println(msg);
}
public static void fun(String temp){
temp = "Wrold";
}
}
//輸出結果:Hello
複製代碼
該範例只有一個解決思路:String類對象內容一旦聲明則不可改變。對象內容的改變依靠的是引用內存地址的改變。ui
咱們都知道String內容從新賦值就是斷開與原內容堆內存的鏈接,從而指向新內容的堆內存地址。因此對當字符串msg傳入fun方法時,字符串temp和msg指向的是同一塊堆內存。當temp內容發生變化時,temp會指向新內容的堆內存。此時temp和msg指向不一樣的堆內存,因此改變temp內容不會影響到字符串msg的內容。 咱們接着看範例三:this
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 ThisKeyWordDemo {
public static void main(String[] args) {
Message msg = new Message("Hello");
fun(msg);
System.out.println(msg.getInfo());
}
public static void fun(Message temp) {
temp.setInfo("World");
}
}
輸出結果:World
複製代碼
實例化msg對象,並傳入字符串」Hello」,此時,字符串info中保存的內容是」Hello」。由於info是String類對象,因此在棧內存中會有一個info對象的標識,並指向的棧內存中保存的是」Hello內容」。實際上msg對象中info變量指向的是另外一個保存着字符串」Hello」的String類對象的棧內存。 而將msg傳入fun方法後,temp對象和msg對象指向同一塊堆內存。當temp.setInfo(「World」); ,改變info字符串的內容時,實際上棧內存中指向」Hello」內容的String類對象info,從新指向了新內容」World」,因此最後輸出結果爲」World」。spa