Re: [問題] 建構子與static 變數

看板java作者 (資工人)時間8年前 (2016/07/14 00:16), 8年前編輯推噓5(504)
留言9則, 6人參與, 最新討論串2/2 (看更多)
※ 引述《birdy1147 (Allen)》之銘言: : 不好意思,想問個比較基礎的問題,我知道題意是要考static與 non-static,但我看了 : 很久都想不通,如下: : class Ans{ : int ns; : static int s; : Ans(int ns){ : if(s<ns){ : s=ns; : this.ns=ns; : } : } : void print( ){ : system.out.println(“ns= ”+ns+“ s= ”+s); : } : } : public class Test{ : public static void main(String[ ] args){ : Ans a = new Ans(50); : Ans b = new Ans(125); : Ans c = new Ans(100); : a.print( ); : b.print( ); : c.print( ); : } : } : 我以為結果會是 ns=50 s=50 : ns=125 s=125 : ns=100 s=100 : 但結果是 ns=50 s=125 : ns=125 s=125 : ns=0 s=125 : 我知道全域變數int在沒有設定的情況下,系統會預設為0 : 所以在new Ans(50);時,經過if判斷式,會被兩個變數設為50 : 所以我以為答案是我想的那樣, : 但從正確答案看來,static int s;會留著之前的50,而int ns;卻會重新歸0 : 想請問這是為什麼呢?我以為重新new過以後,指派給新的物件,應該會是不相關的兩個 : 物件? 你從結果推測出的想法是對的, static field會留下來,instance的field才會重來。 首先,你知道全域變數的話,我猜你可能學過C之類的語言吧? 但在Java中不管是static field還是物件的field都不叫做全域變數, field在中文有些人翻譯成「成員變數」。 不只是開發者取的名字不一樣而已,而是連本質都不一樣。 首先講non-static field這部分跟你說的一樣, 每new一次就會指派新的記憶體空間來存放, 所以每個新產生出來的物件內的變數都不會干擾。 再來是static的部分,我想這部分你誤會了, 以你的敘述來看,應該是把他當成了跟物件內成員變數一樣, 每new一個就會有一個獨立的空間,互不干擾吧? 但這樣不就會變得跟non-static field一樣了嗎? 又何必分成兩種呢? static的特點是「在記憶體中只有一個」, 而且「不用new,打從一開始就存在」。 所以你才會看到變數s的內容一直沒改變。 我不知道你的程式碼是哪裡來的, 但那樣會令人不好理解static與non-static的差別。 我再寫個簡單的範例給你看看兩者個差別。 public class Test{ private static int count; // 紀錄數量 private int number; // 紀錄自己的號碼 public Test(int num){ number=num; count++; } public void print(){ System.out.println("我是"+number +"號,目前加上我已產生"+count+"跟我一樣的物件"); } public static void main(String[] args){ new Test(20).print(); new Test(30).print(); new Test(50).print(); } } 編譯後會輸出: 我是20號,目前加上我已經產生了1個跟我一樣的物件 我是30號,目前加上我已經產生了2個跟我一樣的物件 我是50號,目前加上我已經產生了3個跟我一樣的物件 你會看到我們new了三個Test類別所產生的物件, 三個物件都記得自己被賦予的number。 但count則不一樣,count變數是static的, 不管new了幾次都是共用一個記憶體位置。 所以每呼叫一次就會在建構子內將原本的數字加一, 運用這個特性就產生了紀錄有幾個Test物件的效果。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.132.178.168 ※ 文章網址: https://www.ptt.cc/bbs/java/M.1468426564.A.D7A.html

07/14 13:54, , 1F
推講解
07/14 13:54, 1F

07/14 14:03, , 2F
number=num;
07/14 14:03, 2F
感謝提醒!

07/15 18:35, , 3F
謝謝,你解釋得很清楚,我有比較懂了
07/15 18:35, 3F
不客氣,其實這是我第一次發表文章與編輯回文XD

07/28 12:10, , 4F
長知識了謝~
07/28 12:10, 4F

07/30 12:19, , 5F
補充一點,static連宣告都不用就會存在,可以試試
07/30 12:19, 5F

07/30 12:19, , 6F
看在第一行直接print static變數,並不會有error
07/30 12:19, 6F

07/30 12:20, , 7F
Test.count
07/30 12:20, 7F

07/30 12:20, , 8F
啊 不過好像需要給初始值
07/30 12:20, 8F
field的數字預設是0、物件預設是null 所以我的count的確沒有設初始值

07/31 04:26, , 9F
local變數才需要初值,instance、static都有預設值
07/31 04:26, 9F
※ 編輯: kyleJ (220.132.178.168), 08/15/2016 23:27:25
文章代碼(AID): #1NXcb4rw (java)
討論串 (同標題文章)
文章代碼(AID): #1NXcb4rw (java)