JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java 新手區 » Object/物件導向  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 給新手 - static 成員 [精華]
caterpillar

良葛格

版主

發文: 2613
積分: 70
於 2003-09-01 18:58 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
這篇文章告訴新手一些static的觀念與應用。

其中可以解答一個很常見的問題,為什麼在static函式中只能呼叫static成員(資料成員或函式成員)?例如在main()函式中,這個問題對初學Java時的我一直是個問號,也許一些新手也覺得疑惑。

文章若有謬誤,還請通知我進行修正,糾正我的觀念也免於誤導他人 Smile

=========================================================================
對於每一個基於相同類別所產生的物件而言,其擁有各自的資料成員,然而在某些時候,我們會想要這些物件擁有相同的資料成員,其資料是共享的。

舉個例子來說,在Ball類別中,我們會使用到圓周率的這個資料,對於任一個球而言,圓周率都是一樣的,我們並不需要讓不同的球物件擁有各自的資料成員來記錄圓周率,而這個記錄的值卻是相同,這只會增加記憶體的消耗而已。

我們可以將資料成員宣告為static,被宣告為static的資料成員,它是屬於類別所擁有,而不是個別的物件,我們可以將static視為個別物件所擁有、共享的資料成員。

要宣告static變數,我們只要在宣告資料成員時加上static關鍵字就可以了,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Ball {
    // ....
    public static double PI = 3.14159; // 宣告static資料
                                                                                
    public Ball() {
        // ..
    }
                                                                                
    public Ball(double radius, String name) {
        //...
    }
    public double getVolumn() {
      // ......
    }
}


我們可以在宣告物件之後,使用 . 運算子來存取static資料成員,static變數同樣遵守public、protected與 private的存取限制,所以若您要在類別之外直接存取static變數,必須注意它的權限(例如必須設定為public成員)。

由於static成員屬於類別所擁有,所以在不使用物件名稱的情況下,我們也可以使用類別名稱加上 . 運算子來存取static資料成員,例如:
1
System.out.println("PI = " + Ball.PI);


與static資料成員類似的,我們也可以宣告類別的成員函式為static函式,例如如果我們在Ball類別中想要提供設定PI值與傳回PI值的函式,如果這個PI值是屬於共用的數值(已經被宣告為static且為private成員),則我們不用在乎是由哪個物件來呼叫設定函式,我們可以將這些函式宣告為static,例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Ball {
    // ....
    private static double PI = 3.14159; // 宣告static的private資料
                                                                                
    // ....
                                                                                
    public static double getPI() {  // 宣告static函式
        return PI;
    }
                                                                                
    public static void setPI(double pi) {
        PI = pi;
    }
}


與static資料成員一樣的,我們可以透過物件名稱使用 . 運算子來存取static函式,例如:
1
System.out.println("PI = " + Ball.getPI());


static資料與函式的作用之一,是提供公用類別函式,例如將數學常用常數或計算公式,以static宣告並撰寫,之後我們可以透過類別名稱來管理與取用這些函式,例如像Math.Exp、Math.Log()、Math.Sin()等等的static常數或函式等,事實上,像PI這個常數,在Math.PI就有定義,我們可以直接呼叫使用。

由於static成員是屬於類別而不是物件,所以當您呼叫static函式時,並不會傳入物件的位置參考,所以static函式中不會有this參考,由於沒有this參考,所以在Java的static函式成員中不允許使用非static成員,因為程式沒有this來參考至物件位址,也就無法辨別要存取哪一個物件的成員,事實上,如果您在static函式中使用非static資料成員,在編譯時就會出現以下的錯誤訊息:
1
non-static variable test cannot be referenced from a static context


或者是在static函式中呼叫非static函式,在編譯時就會出現以下的錯誤訊息:
1
non-static method showMe() cannot be referenced from a static context


caterpillar edited on 2005-08-21 19:18
reply to postreply to post
良葛格學習筆記
作者 Re:給新手 - static 成員 [Re:caterpillar]
Duncan

還隱隱作痛

版主

發文: 7816
積分: 39
於 2003-09-01 21:43 user profilesend a private message to usersend email to Duncanreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
caterpillar wrote:

我們可以在宣告物件之後,使用 . 運算子來存取static資料成員,static變數同樣遵守public、protected與 private的存取限制,所以若您要在類別之外直接存取static變數,必須注意它的權限(例如必須設定為public成員)。


這一點講的並沒有錯,的確可以透過 object 以 member access operator . 來 access static member,這和透過 class name 來取得 static member 兩者感覺起來一樣,但語意上不太一樣,至少對 sun 的編譯器來說是不一樣的。前者的寫法會使得 object reference 被 push 進 stack 隨即又 pop 掉,所以會平白犧牲掉一點效率,後者則不會。你可以說 sun 的編譯器很笨,但還是要瞭解這一點。


reply to postreply to post

給我
辣味豆腐 其餘免談
作者 Re:給新手 - static 成員 [Re:Duncan]
Yoshi

塵世中一個迷途小書僮

版主

發文: 874
積分: 22
於 2003-09-01 21:57 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Duncan wrote:
這一點講的並沒有錯,的確可以透過 object 以 member access operator . 來 access static member,這和透過 class name 來取得 static member 兩者感覺起來一樣,但語意上不太一樣,至少對 sun 的編譯器來說是不一樣的。前者的寫法會使得 object reference 被 push 進 stack 隨即又 pop 掉,所以會平白犧牲掉一點效率,後者則不會。你可以說 sun 的編譯器很笨,但還是要瞭解這一點。


而且這樣的寫法也會造成混淆, 印象中Code Convention也不建議這麼寫
都是建議使用ClassName.staticMember


reply to postreply to post
YOSHI!
作者 Re:給新手 - static 成員 [Re:Yoshi]
saijone

Web Services

版主

發文: 470
積分: 24
於 2003-09-01 23:51 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Yoshi wrote:
而且這樣的寫法也會造成混淆, 印象中Code Convention也不建議這麼寫
都是建議使用ClassName.staticMember

If my recollection is correct, some ide, like eclipse, gives warning for instance.classStaticThing.


saijone edited on 2003-09-01 23:55
reply to postreply to post
You don't need a reason to help people
作者 Re:給新手 - static 成員 [Re:caterpillar]
yysun

JavaNewHand



發文: 64
積分: 0
於 2004-02-06 06:43 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
不好意思....
Ducun說的
的確可以透過 object 以 member access operator . 來 access static member,這和透過 class name 來取得 static member 兩者感覺起來一樣,但語意上不太一樣,至少對 sun 的編譯器來說是不一樣的。
問一下member access operator和access static member是什麼啊...
英文不太好...謝謝^^


anthonycs edited on 2004-05-16 19:04
reply to postreply to post
作者 Re:給新手 - static 成員 [Re:yysun]
weaker

小屁屁∼



發文: 379
積分: 4
於 2004-02-06 09:33 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list

紅色部分應該就是 member access operator


anthonycs edited on 2004-05-16 19:04
reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
yysun

JavaNewHand



發文: 64
積分: 0
於 2004-02-06 16:13 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
原來如此,了解了,thx...^^

reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
jojo1293





發文: 10
積分: 0
於 2004-12-23 15:51 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
sorry 上篇出現了笑臉@@"第一次post 不太熟練 ...
請問一下
1
2
3
4
5
6
7
8
9
10
11
public class Test{
    private static int a;
    public static void main(String args[]){
      modify(a);
      System.out.println(a);
    }
  
    public static void modify(int a){
      a++ ;
    }
}


答案為甚麼是0 ??
int 初值為0 ...
然後在main() 中呼叫modify(),那應該會執行到a++ ??
但是答案還是0...想不通....請各位幫幫忙解我疑惑...~~


tekwei edited on 2004-12-23 16:08
reply to postreply to post
作者 Re:給新手 - static 成員 [Re:jojo1293]
tekwei

系統穩定



發文: 978
積分: 4
於 2004-12-23 16:13 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
jojo1293 wrote:
答案為甚麼是0 ??
int 初值為0 ...
然後在main() 中呼叫modify(),那應該會執行到a++ ??
但是答案還是0...想不通....請各位幫幫忙解我疑惑...~~

問題竟然跟內文的發問者差不多一樣。。

see: modify的問題....


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
jojo1293





發文: 10
積分: 0
於 2004-12-23 16:39 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
原來是跟變數的存取空間有關~..
一直在static 的問題上打轉~

謝謝喔!!Big Smile


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
i25959341





發文: 61
積分: 0
於 2004-12-23 20:30 user profilesend a private message to usersend email to i25959341reply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
every book that i read about never tell the real different between
instance and static variable and now i understand. thank for that


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
jojo1293





發文: 10
積分: 0
於 2004-12-24 11:18 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class staticModifier
{
  int counter1 = 0;
  static int counter2 = 0;
  
  public void Increase(String s)
  {
    counter1++;
    counter2++;
    System.out.print(s + "'s counter1 = " + counter1);
    System.out.println("; counter2(static) = " + counter2);
  }
  
  public static void main(String argv[])
  {
    staticModifier sta1 = new staticModifier();
    staticModifier sta2 = new staticModifier();
    
    sta1.Increase("sta1");
    sta1.Increase("sta1");
    sta2.Increase("sta2");
  }
}

列出的結果是
1
2
3
sta1's counter1 = 1; counter2(static) = 1
sta1's counter1 = 2; counter2(static) = 2
sta2's counter1 = 1; counter2(static) = 3

有點小疑問~想問問大家我的想法是否正確

counter1 是instance var ..也是當物件產生後..才會存在在記憶體~
在main()產生了兩個物件...當物件產生...sta1 ,sta2 物件分別配置記憶體
並指向counter1
sta1 物件不在使用的話..那counter1 就還給記憶體了?
第2行的答案..counter1 為2 ..是因為..物件還在使用....所以繼續累加***?

那counter2累加的原因是因為他是static 變數..所以這個程式執行完了..
才會還給記憶體?

不知道這樣的想法有沒有錯誤..請大家指點~~


jojo1293 edited on 2004-12-24 11:23
reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
i25959341





發文: 61
積分: 0
於 2004-12-26 05:17 user profilesend a private message to usersend email to i25959341reply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
THANK YOUS
THIS QUESTION HAVE MESSIN AROUND WITH ME FOR YEARS
I FINALLY KNOW WHY PEOPLE USE INSTANCE INSTEAD OF STATIC


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
elvis_meng





發文: 8
積分: 0
於 2005-01-28 16:23 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
對. 你只要想像: 物件sta1與sta2各自擁有相同名稱的物件counter1, 但是它們佔據不相同的記憶體, 但是counter2定義為static, 為類別變數, 所以此類別變數為sta1與sta2共同擁有, 也就是counter2在記憶體中只有存在一個. 這樣想就容易多了.

reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
sgchris





發文: 1
積分: 0
於 2005-03-28 13:10 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我們將資料成員宣告為static,优势是屬於類別所擁有,而不是個別的物件,那么宣告為static的資料成員可以共享。
那宣告類別的成員函式為static函式,优势是什么呢?
可以在非static函式中使用static資料成員吗?


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
java_member





發文: 21
積分: 0
於 2005-05-29 13:09 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
整理了大大的東西..........

類別包含"資料"和"操作"(或稱方法, 函式).
當產生N個物件時, "資料"被產生N分, 但操作還是只有一份.
因此, "操作"只是被共用來操作N個物件的資料用.

問題是, "一般的操作只有在物件產生時才可以呼叫,
而"static操作"則在物件產生前就可以呼叫.


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
adoo





發文: 87
積分: 0
於 2005-05-31 22:18 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
其實這麼說都太複雜了

static 翻做 靜態 就是說 一開始 就保留給 宣告成 static 的 成員 或函式
如果以c++來說 就是固定一個記憶體位置給 宣告成 static 的 成員 或函式
不管你 new 幾個物件 , static 的成員或函式 始終指向同樣的記憶體位置
所以當你 更改 static 的 成員的值時
所有 new 出來的物件 中的static 的 成員的值就都會變了


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
je





發文: 112
積分: 2
於 2005-06-24 21:25 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我們將資料成員宣告為static,优势是屬於類別所擁有,而不是個別的物件,那么宣告為static的資料成員可以共享。
那宣告類別的成員函式為static函式,优势是什么呢?
可以在非static函式中使用static資料成員吗?


1. 最常見的就是 main(),宣告為 static 可在任何物件存在之前被呼叫。
2. 在需要建立多個 class 使用的公用 method 時: 如 Math 類別,目的在公用,而不需要擁有自己的狀態,用 public static 會較方便,其它像是: java.lang.System、java.swing.SwingUtilites…等。
3. 建立只在 class 中使用的「外包工作用的 method」: 避免被一些 實體 method 任意存取 實體variable/field。因為 static method 沒有 this,不能擅自呼叫 實體method 或 實體variable。


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
glorywine_1983





發文: 10
積分: 0
於 2005-07-12 18:32 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
不错
有学到不少
还要在仔细琢磨一下!


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
Liaostake





發文: 2
積分: 0
於 2005-07-15 00:43 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
這一篇文章,大大講解的真清楚,真是受益良多.....

reply to postreply to post
作者 Re:給新手 - static 成員 [Re:adoo]
demijava2

Fight-F-U



發文: 74
積分: 1
於 2005-07-26 11:47 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
adoo wrote:
其實這麼說都太複雜了

static 翻做 靜態 就是說 一開始 就保留給 宣告成 static 的 成員 或函式
如果以c++來說 就是固定一個記憶體位置給 宣告成 static 的 成員 或函式
不管你 new 幾個物件 , static 的成員或函式 始終指向同樣的記憶體位置
所以當你 更改 static 的 成員的值時
所有 new 出來的物件 中的static 的 成員的值就都會變了


這樣講我就明白了。


reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
JavaPiano





發文: 2
積分: 0
於 2005-07-28 08:29 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我看完書中的描述,再看各位的解釋後,對於 static 更了解。
謝謝!


reply to postreply to post
音樂 我用鋼琴來詮釋
程式 我用Java來撰寫
作者 Re:給新手 - static 成員 [Re:caterpillar]
ha129466





發文: 14
積分: 0
於 2006-06-13 23:12 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
更明白清楚些了 謝謝各位先進

reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
chain710915





發文: 71
積分: 0
於 2006-06-27 17:49 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
嗯嗯!!釐清了一些概念!感恩

reply to postreply to post
作者 Re:給新手 - static 成員 [Re:caterpillar]
joric





發文: 1
積分: 0
於 2007-02-12 17:27 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
好文!!

reply to postreply to post
go to first page go to previous page  1   2  go to next page go to last page
» JWorld@TW »  Java 新手區 » Object/物件導向

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8