2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

java 傳值 vs. 傳引用

 pstn 2007-11-22

java 傳值 vs. 傳引用

java程序的函數(shù)調(diào)用到底是傳值呢還是傳參呢?這可是個(gè)難纏的問(wèn)題,如果搞不清楚還是挺容易出錯(cuò)的:P對(duì)于這個(gè)問(wèn)題,最經(jīng)典的解釋莫過(guò)于“java函數(shù)是傳值的,java函數(shù)傳遞的參數(shù)是對(duì)象的引用”
這兩句話好像初聽上去有點(diǎn)繞,不過(guò)意思倒是表達(dá)得蠻精確的。
我看到過(guò)幾個(gè)解釋這個(gè)問(wèn)題的例子,不過(guò)個(gè)人感覺看過(guò)例子之后還是只知道是什么不知道為什么,停留在照貓畫虎的水平上還是挺容易出問(wèn)題的。所以舉例子之前,先從jvm的實(shí)現(xiàn)原理上有個(gè)了解應(yīng)當(dāng)是不無(wú)裨益的。jvm的結(jié)構(gòu)圖前一陣子貼到blog上了,那可是從“深入java虛擬機(jī)”這本巨牛的書上看來(lái)的,絕對(duì)有權(quán)威性。從jvm的結(jié)構(gòu)圖上可以看出來(lái),jvm在實(shí)現(xiàn)的時(shí)候?qū)儆谒膬?nèi)存分為五部分,其中程序代碼(嚴(yán)格的說(shuō)應(yīng)當(dāng)是字節(jié)碼)是放在java棧的棧幀中,而對(duì)象是從堆中分配的,堆這個(gè)東西我看可以理解成“對(duì)象池”。程序和程序中需要用到的對(duì)象放在兩個(gè)相對(duì)獨(dú)立的區(qū)域中,那么程序怎么使用對(duì)象呢?答案是程序中真正使用對(duì)象的地方其實(shí)只是聲明了一個(gè)對(duì)象的引用,也就是把堆中分配了的相應(yīng)對(duì)象的地址放到引用中,棧和堆之間就是通過(guò)一個(gè)一個(gè)的引用來(lái)聯(lián)系的。引用嘛,我理解就是一個(gè)指針常量,指針常量又是個(gè)什么東西呢?說(shuō)白了,就是一個(gè)無(wú)符號(hào)整數(shù),這個(gè)整數(shù)所表達(dá)的是引用對(duì)象的地址。好了,這下清楚了,不管是基本類型變量(int,float,double什么的)還是對(duì)象,相應(yīng)的內(nèi)存地址中存放的都是一個(gè)數(shù)(無(wú)符號(hào)整數(shù),整數(shù),浮點(diǎn)數(shù)等)。傳遞參數(shù)的時(shí)候傳遞的就是相應(yīng)內(nèi)存地址中的數(shù),所以說(shuō)“java函數(shù)是傳值的”。當(dāng)然,這個(gè)數(shù)對(duì)于基本類型和對(duì)象類型來(lái)說(shuō)意義是不一樣的,對(duì)于基本類型這個(gè)數(shù)就是其值本身,傳遞值的結(jié)果就是,改變新的變量的值不影響舊的變量的值;而對(duì)于對(duì)象來(lái)說(shuō)這個(gè)數(shù)是它的地址,傳遞這個(gè)值就相當(dāng)于傳遞了真實(shí)對(duì)象的引用,傳遞了引用或者說(shuō)是地址的結(jié)果就是變化會(huì)全局可見,所以又可以說(shuō)“java函數(shù)傳遞的參數(shù)是對(duì)象的引用”。
唔,松口氣啦。經(jīng)過(guò)上面這一小堆討論,不難理解為什么java在傳遞參數(shù)時(shí)對(duì)于基本類型和對(duì)象表現(xiàn)不同:)
現(xiàn)在開始舉例了,舉網(wǎng)上搜來(lái)的例子,看看是不是比原來(lái)沒(méi)有上面的解釋的時(shí)候好理解一點(diǎn)?
public class TestRef
{
 public static void main(String[] args)
 {
  ValueObject vo1 = new ValueObject("A", 1);
  System.out.println("after vo1: " + vo1.getName()); //=A
 
  changeValue1(vo1);
  System.out.println("after changeValue1: " + vo1.getName());
                //=A1, changed
 
  changeValue2(vo1);
  System.out.println("after changeValue2: " + vo1.getName());
                //=A1, changeValue2內(nèi)部的賦值不會(huì)影響這里。
 }
 /**
  * 使用vo1自身的函數(shù)對(duì)其內(nèi)部數(shù)據(jù)進(jìn)行改變是有效的,函數(shù)外可反映出來(lái),
  * 因?yàn)檫@是對(duì)對(duì)象本身的操作
  * 這種object稱為可變的(mutable)
  * @param vo1
  */
 private static void changeValue1(ValueObject vo1)
 {
  vo1.setName("A1");
 }
 /**
  * 在函數(shù)內(nèi)給vo1重新賦值不會(huì)改變函數(shù)外的原始值,因?yàn)檫@種改變了引用的指向
  * @param vo1
  */
 private static void changeValue2(ValueObject vo1)
 {
  vo1 = new ValueObject("B", 2);
  System.out.println("inside changeValue2: "+ vo1.getName());
                //=B,賦值操作引起的結(jié)果變化僅在changeValue2內(nèi)部有效
 }
}
class ValueObject
{
 
 public ValueObject() {}
 
 public ValueObject(String name, int id)
 {
  this.name = name;
  this.id = id;
 }
 
 private String name;
 private int id;
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
}
java中對(duì)象的每個(gè)實(shí)例(就是對(duì)象)內(nèi)存地址是唯一的,它一旦被創(chuàng)建,能夠?qū)@個(gè)地址進(jìn)行操作的就是其本身,如果ValueObject類中沒(méi)有public void setName之類的方法對(duì)這個(gè)類的實(shí)例中的數(shù)據(jù)進(jìn)行修改的話,程序是沒(méi)有任何別的方法可以修改ValueObject類的實(shí)例中的數(shù)據(jù),這個(gè)就是java的封裝特性。對(duì)于不提供修改內(nèi)部數(shù)據(jù)的方法的類,我們稱為不可變(immutable)的類。在函數(shù)中對(duì)傳入的參數(shù)變量進(jìn)行賦值操作,只能在函數(shù)范圍內(nèi)改變局部變量指向的引用地址,但是不會(huì)改變?cè)嫉刂返膬?nèi)容。因此,在changeValue2(...)函數(shù)內(nèi)部的vo1和函數(shù)外的vo1雖然名字相同,但是實(shí)際上是不同的實(shí)例變量,只不過(guò)指向了和函數(shù)外的vo1同樣的地址,所以當(dāng)我們用vo1=... 對(duì)其進(jìn)行賦值的時(shí)候,只不過(guò)是把函數(shù)內(nèi)的臨時(shí)變量指向了新的地址,并沒(méi)有改變?cè)紇o1內(nèi)存地址中的內(nèi)容。這就是在運(yùn)行changeValue2(...)之后,vo1的值在main范圍內(nèi)仍然沒(méi)有被修改的原因。而changeValue1里面是調(diào)用的ValueObject本身的function來(lái)更改其內(nèi)容,因此是原始內(nèi)存地址中的數(shù)據(jù)被更改了,所以是全局有效的.
總結(jié):
對(duì)于引用類型的傳參也是傳值的,傳的是引用類型的值,其實(shí)就是對(duì)象的地址。
1. java參數(shù)傳遞值的。
2. java所有對(duì)像變量都是對(duì)像的引用。
不知道我解釋清楚沒(méi),要是還是不能理解java參數(shù)傳遞的原理,強(qiáng)烈推薦看看“深入java虛擬機(jī)”一書的第五章,中文翻譯的不是特別出色,可以看看英文原版,應(yīng)該比中文版好懂:)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多