Re: [問題] 類別的方法中為何可以建立本身類別的物件?

看板java作者 (墳墓)時間14年前 (2009/11/28 05:41), 編輯推噓12(1203)
留言15則, 12人參與, 最新討論串5/6 (看更多)
※ 引述《aMaa (aMa)》之銘言: : 今天我有實作測試一下, : 不管是public static void main還是一般method都可以new本身類別的物件 : : 只是不知道原理為何? 【離題】 說實話,這個討論串讓我想到之前在自己的部落格上寫到的這一篇 雜記裡關於程式語言學習的部份,有問到到底在學習程式式語言的 時候,要從何處入手【註 0】。 【註 0】 http://bone.twbbs.org.tw/blog/archives/1173 這一串討論看下來,看來看去,只有一個想法:會有這種疑問,根 本就是因為不了解整個 von Neumann架構/程式語言/編譯器/機 器語言/虛擬機器之間的關連所造成的嘛…… 以下,可能很長,可能很多看似無關緊要的東西(就算你不懂,你 的程式還是可以動),可是我自己認為這是值得去了解的基礎,如 果你真的用心了解下面所講的東西,基本上就不會再出現類似的疑 惑了。 【回題】 其實原 PO 的問題本質上和另一個問題一樣:為什麼像是下面的遞 迴程式裡,第 6 行的時候,明明 sum 還明有定義完,卻可以呼 叫自己呢? // 用遞迴計算 1 + 2 + ... + n 1 int sum (int n) { 2 if (n == 1) { 3 return 1; 4 } 5 6 return n + sum(n-1); 7 } 為什麼下面的程式裡,Node 明明還沒定義完,裡頭卻又出現另一 Node 呢? 1 class Node { 2 private Node next; 3 } 我真的很想大叫:不要鬧了!大家到底知不知道 Java 程式語言/ Bytecode / Virtual Machine / von Neumann 電腦架構 / 原生可 執行檔/器與語之間的關係,到底知不知道一個 Java 程式是怎麼 執行的啊?! 請問你自己一個問題:Java 程式執行的時候,是執行你寫的原始 碼嗎? (答:不是,實際上執行的是 bytecode,也就是 javac 翻譯出來 的 .class 檔) 請問你自己第二個問題:你在執行你的 Java 程式 (Bytecode) 的 時候,你知道 Bytecode 到底是什麼東西,做什麼用的嗎? (答:可以將 Bytecode 視為一套虛擬的『類機器語言』,將其交 由 Virtual Machine 解譯後,可以產生電腦 CPU 真正能夠理解 的機器語言指令) 請問你自己第三個問題:你知道什麼叫 von Neumann 架構嗎?你知 道一個『原生電腦程式』是如何在 von Neumann 架構上執行的嗎? (答:如果不知道,請參閱『小人電腦』【註 1】,裡面是簡化版 的說明,但基本上目前的所有電腦都不脫離這個架構。) 【註 1】http://programming.im.ncnu.edu.tw/Chapter2.htm 如果你看完了上面的小人電腦,請你問你自己第四個問題:你在小 人電腦裡,有看到『資料結構』、『函數』、『物件』、『類別』 這種東西嗎? (答:沒有,只有記憶體/指令/暫存器/Program Counter ,而 且記憶體位置好像也都知能存數字【註2】) (謎之音:那我的函數、物件、資料夾構在哪裡?提示:我們還有 可執行檔以及 Bytecode 這兩個東西沒講到。) 【註 2】嚴格來說這並不正確 請再問你自己第五個問題:你知道我們剛剛『定義』出來的計算總 合的函式,如果翻譯成小人電腦的機器語言,用上述網頁中的機器 語言表示出來會長什麼樣子嗎? (答:你會看到 sum(n-1) 被翻成一個 CALL 指令,其參數 XX 的 部份會是此函數的開頭,而 return 會被翻成 RETURN ,如果你不 知道這是什麼意思,請把小人電腦再認真看一次,並注意最後一個 函數呼叫的例子) 以上,是回答為什麼函數可以呼叫自己。 接下來,請再問你自己:記憶體 / 指標 / 參考 / 物件之間,究 竟是什麼關係,你知道第二個 Node 的 Java 程式碼,被載入到記 憶體後,到底長什麼模樣嗎? (答:指標和參考本質上都是相同的,都是『記憶體位置』) 這不就很明顯了嗎?private Node next,說的是『next 是一個記 憶體位置,而且這個記憶體位置應該要指到一個長得像 Node 的物 件』。 但 next 真的必需指到 Node 物件嗎?(提示:多型/強制轉型/執 行期錯誤)他不過就是個數字,來表示記憶體位置,誰管他指到什 麼地方啊! 所以說,這有什麼好訝異的?不過就是『在 Node 的這個物件裡, 有一個欄位是一個數字,他指到某一個記憶體的位置,而這個記憶 體位址上的內容,應該要是另一個Node 物件(但不必然是)。』 這很直覺,很正常啊! 最後,回到原 PO 的問題,如果再把原 PO 的問題更簡化,可以問 另一個問題,那就是以下的 Java 程式碼是否合法,如果它合法的 話,執行這段 Java 程式碼裡的 test() 到底會發生什麼事,記憶 體裡產生了哪些變化? class Hello { public void test () { Hello hello = new Hello(); } } public class Test { public static void main (String [] args) { Hello hello = new Hello (); hello.test (); } } 接下來,你要問你自己,Java 裡 new 出來的物件,到底在是住在 記憶體的哪裡?而指到各物件的參考又活在哪裡?是在 Stack 還 是在 Heap ?指標裡存的又是什麼? 再來, hello.test() 這一行會翻譯成什麼小人電腦的組合語言? (提示:Method call 和 function call 本質上是一樣的東西) 如果,你能回答出以上的問題,基本上就不會有『為什麼函數沒有 定義完還可以呼叫自己,為什麼物件可以 new 自己,為什麼明明 就還沒定義完,Node 裡卻可以有 Node』 的這種疑問了。 謎之音:所以說,這篇『爪哇學校的危害』【註 3】還是有他的道 理在的啊! 【註 3】英文版:http://0rz.tw/f00Zg 中文版:http://0rz.tw/g3JZo -- ~ 白馬帶著她一步步地回到中原。白馬已經老了,只能慢慢地走, 'v' Brian Hsu 但終是能回到中原的。江南有楊柳、桃花,有燕子、金魚…… // \\ ( 墳 墓 ) /( )\ 但這個美麗的姑娘就像古高昌國人那樣固執。 【白馬嘯西風】 ^`~'^ http://bone.twbbs.org.tw/blog 『那都是很好很好的,可我偏不喜歡。』 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 59.120.199.114 ※ 編輯: brianhsu 來自: 59.120.199.114 (11/28 05:46)

11/28 06:23, , 1F
剛剛查了一下 是von Neumann
11/28 06:23, 1F
※ 編輯: brianhsu 來自: 59.120.199.114 (11/28 06:35)

11/28 06:36, , 2F
謝啦,已更正。:p
11/28 06:36, 2F

11/28 07:36, , 3F
可以 M 起來放精華區了..
11/28 07:36, 3F

11/28 08:05, , 4F
從太底層的事情講太高層的現象,沒太大意義
11/28 08:05, 4F

11/28 08:19, , 5F
嘖嘖,聽說我好像是小板主吼 (偷偷收起來 XD
11/28 08:19, 5F

11/28 09:52, , 6F
11/28 09:52, 6F

11/28 09:59, , 7F
推 “這是值得去了解的基礎”
11/28 09:59, 7F

11/28 10:05, , 8F
可惜不是每個人都有閒有機會有能力有心從基礎開始
11/28 10:05, 8F

11/28 11:24, , 9F
萬分感謝!!
11/28 11:24, 9F

11/28 13:54, , 10F
不曉得會不會有神人來說「你們到底了不瞭解機器碼...」XD
11/28 13:54, 10F

11/28 15:43, , 11F
然後被轉送去PLT... (大誤)
11/28 15:43, 11F

11/28 19:44, , 12F
所以 Object 的 toString 也是這個意思囉?
11/28 19:44, 12F

11/28 22:41, , 13F
感謝分享 :)
11/28 22:41, 13F

11/29 01:05, , 14F
推學長墳墓大大XD
11/29 01:05, 14F

11/30 07:30, , 15F
純推學長登出後在JAVA板的第一篇文章 XD
11/30 07:30, 15F
文章代碼(AID): #1B44TpyU (java)
討論串 (同標題文章)
本文引述了以下文章的的內容:
以下文章回應了本文
完整討論串 (本文為第 5 之 6 篇):
文章代碼(AID): #1B44TpyU (java)