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

作者: kyleJ (資工人)   2016-07-14 00:16:01
※ 引述《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物件的效果。
作者: smallmac (洨麥克)   2016-07-14 13:54:00
推講解
作者: quadro (屎凱)   2016-07-14 14:03:00
number=num;
作者: birdy1147 (Allen)   2016-07-15 18:35:00
謝謝,你解釋得很清楚,我有比較懂了
作者: charlie1081 (神奇薩滿)   2016-07-28 12:10:00
長知識了謝~
作者: poolongkong (普攏貢)   2016-07-30 12:19:00
補充一點,static連宣告都不用就會存在,可以試試看在第一行直接print static變數,並不會有errorTest.count啊 不過好像需要給初始值
作者: ssccg (23)   2016-07-31 04:26:00
local變數才需要初值,instance、static都有預設值

Links booklink

Contact Us: admin [ a t ] ucptt.com