Re: [問題] 問一個 記憶體 和 GC 的問題

看板java作者 (雪.狼.湖)時間19年前 (2006/01/31 23:54), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串5/5 (看更多)
※ 引述《qrtt1 (thinking in java)》之銘言: : ※ 引述《jackyhuang (雪.狼.湖)》之銘言: : alias是很重要的一個觀念。 : 因為若不了解則在使用物件時可能隱藏了bug : 詳細解說請參考thinking in java,前面介紹reference的章節, : 與附錄介紹clone的章節 你和我對alias的對象指的不一樣 我說你寫"reference alias"會混淆的原因 是因為會讓人以為是"reference's alias" 而書上寫的是"alias a reference to an object" : java中唯一有operator overload的物件只有String : 唯一合法改變物件內容的方使是呼叫其公用方法(或其他許可的情況) 這不是我舉這個例子的原意 : 我將原生變數與物件參考分開講是基於實際上的結果 : 原生變數的副本並不能互相影響, 是獨立的 : 而物件參考的副本, 就是別名。會不會互相影響視其是否為可變動物件而定。 : 若要其互相獨立需執行clone方法。 複製的reference value彼此也是互相獨立的 只是他們指向同樣的一個object instance 所有的東西你在Java當然都講得通,但是如果把C++的用詞混進來(reference, alias...) 我覺得這樣的說法只會讓人更混亂,reference value亦是被call by value 複製一份過去的行為,有那麼難接受嗎? 我不敢說thinking in java寫得不清楚 但我認為JLS寫得很清楚,它是官方文件權威性不會比作者低 我個人猜thinking in java的作者是從他過去對C/C++的經驗,角度去解釋java 我認為這已經接近在用詞上的爭論,所以我也就不再回這篇文章 最後我以前輩TAHO的文章做為結尾,我認為TAHO前輩這篇文章已經足以終結這個討論串 -- TAHO前輩的文章 發信人: companion.bbs@bbs.nsysu.edu.tw (癡人), 看板: java 標 題: call by XXX 必也正名乎.... 發信站: 中山計中美麗之島 (Tue Oct 30 12:38:01 2001) 轉信站: nhctc_bbs!news.NHCTC!ctu-peer!news.nctu!news.cis.nctu!News.Math.NCTU!ne Origin: bbs.nsysu.edu.tw 好吧..... 既然要討論 那就要先來正名一下 首先 得先釐清 何謂 call by value 又何謂 call by reference 當然在這之前 要先定義好 什麼是 value 什麼是 reference 因為最近在翻譯 JLS 所以我引用 JLS 裡面對這兩個詞的用法 ( 這份文件應該可以代表 sun 的官方看法吧? ) 據我的感覺 在 Java 中 有兩種 Type 也就是 primitive type 跟 reference type 這兩種 Type 限制了 variable 所能握有(hold) 的 value 種類 而所謂的 value 當然就是指 "值",也就是資料的直接內容 (指其位元碼,而非其代表的意義) 所謂的 primitive type 我喜歡翻譯為基本型別 這種型別的 value 被稱之為 primitive value 這種 value 所代表的就是一個數量 一個大小 並不是用來代表其他任何東西的 所謂的 reference type 一般我們翻譯成 "參考型別" 這種型別的 value 被稱為 reference value 而這個 reference value 並非是實際上應用的東西 不是一個數量 它只是個參考 是一個可以 指向物件 的參考 也就是可以根據 reference value 去找到物件 但是 reference value 並不等於是物件 ( 其實 reference value 跟 reference 混用 並不會照成太大的困擾 ) 也就是說 value 可分為兩種,分別為 primitive value 跟 reference value 而所謂的 variable(常常翻譯成變數) 則可以握有(hold) 這兩種東西 當 variable hold 的是 primitive value 時 我們稱這個 variable 是 primitive type 的變數 反之 當 variable hold 的是 reference value 時 我們稱這個 variable 是 reference type 的變數 ( 注意,這句話是說 它是個 "參考型別的變數",而非 "它是個參考" ) 所以 primitive value,reference value,variable, primitive type,reference type,object 分別是代表不同的意義 不同的東西 不可混用 所以下面這兩個敘述 int i = 1; String str = "test"; 其中 i 跟 str 是 "變數" "test" 是個字串的生成表示式,會生成 String 物件 1 是個整數的直譯字(literal) int 跟 String 是 type 我們是看不到 value 的,他們是被 hold 在變數中的 另外 i 跟 str 雖然都是變數 但是 JVM 可以知道 i 是 primitive type 的變數, str 是 reference type 的變數 至於要分辨那屬於那種 type 的原因 是要知道當我們使用變數 hold 住的 value 時 (當然是一堆位元碼) 這些碼代表的到底是 primitive value 還是 reference value 比如說如果他的內容是 749452 那這個 749452 代表的是一個數量值,還是記憶體中的一個位置區塊 請注意: 嚴格來說 str 是個 variable 是一個 reference type 的 variable str 不是一個 參考 而是握有參考值 str 也不是一個 物件 而是握有指向物件的參考值 平常我們在說 "str 物件" 只是為了方便起見 在討論這些東西時 要說清楚才行 於是 如果所謂的 call by value,是把 value 複製一份給別人 那麼 call by reference 就是把 reference 複製一份給別人 在這種前提下稱 "Java 在傳遞 reference type 引數時 是 call by reference" 是沒有問題的 Java 確實是把 variable 所 hold 的 reference value 複製一份 或者可以把 call by reference 改稱為 call by reference value 會更清楚 這種情況下甚至可以說 call by reference 是 call by value 的一種 而 "在傳遞 primitive type 的引數時,是 call by primitive (value)" call by primitive 也是 call by value 的一種 如果是這樣, 那 Java 是 call by reference (value) 也是 call by value 因為 reference value 也是一種 value 這時候去爭論 Java 是 call by value 還是 call by reference 有甚麼意義呢? 如果把 variable reference object 混為一談 value 的意義又沒有規範清楚 把人家說的 call by reference 當成 call by object 的意思 然後把別的語言的用法套到 Java 上 那就亂成一團 也難怪會吵翻天了....... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.121.212.1
文章代碼(AID): #13tuX4gW (java)
文章代碼(AID): #13tuX4gW (java)