## Java編程那些事兒65——static修飾符
鄭州游戲學院陳躍峰
出自:[http://blog.csdn.net/mailbomb](http://blog.csdn.net/mailbomb)
### 8.7 修飾符
修飾符的作用是讓被修飾的內容具備特定的功能,在程序中合理使用修飾符可以在語法和功能上實現很多需要的效果。Java語言中的修飾符主要有5個:static、final、native、abstract和synchronized。這里首先講解static、final和native的作用。
#### 8.7.1 static修飾符
static關鍵字的中文意思是靜態的,該修飾符可以修飾成員變量,成員常量和成員方法。使用該關鍵字修飾的內容,在面向對象中static修飾的內容是隸屬于類,而不是直接隸屬于對象的,所以static修飾的成員變量一般稱作類變量,而static修飾的方法一般稱作類方法。另外,static還可以修飾代碼塊,下面進行詳細的介紹。
##### 8.7.1.1 靜態變量
static修飾的變量稱作靜態變量。靜態變量和一般的成員變量不同,一個類在加載到內存時,靜態變量只初始化一次,也就是說所有對象的靜態變量在內存中都只有一個存儲位置,每個對象中的靜態變量都指向內存中同一個地址,它是在所有的對象之間共享的數據。另外靜態變量在引用時比較方便。所以一般在需要實現以下兩個功能時使用靜態變量:
1.? 在對象之間共享值時
2.? 方便訪問變量時
下面首先說一下非靜態變量(沒有static修飾符修飾的成員變量)在內存中如何存儲的。示例代碼如下:
~~~
???????? //文件名Box.java
???????? public class Box{
?????????????????? int length;
?????????????????? int width;
?????????????????? int height;
?????????????????? public Box(int l,int w,int h){
??????????????????????????? length = l;
??????????????????????????? width = w;
??????????????????????????? height = h;
?????????????????? }
???????? }
???????? //文件名TestBox.java
???????? public class TestBox{
?????????????????? public static void main(String[] args){
??????????????????????????? Box a = new Box(10,20,30);
??????????????????????????? Box b = new Box(40,20,10);
?????????????????? }
???????? }
~~~
則對象a和對象b在內存中的存儲格式如下圖所示:
對象a?????????????????????????????? ??對象b
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">10</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">20</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">30</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">length</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">width</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">height</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">40</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">20</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">10</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">length</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">width</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">height</font></span></p></div></td></tr></tbody></table>
從上面的圖可以看出,非靜態變量的值在每個對象中都有獨立的存儲空間,不同對象間這些值之間沒有管理,也就是說每個對象都為內部的每個非靜態的變量分配獨立的存儲空間,所以每個對象中非靜態變量是隸屬于對象,也就是說在每個對象中可能是不同的。
簡單介紹了非靜態變量在對象中的存儲以后,下面再來看一下靜態變量是如何進行存儲的。示例代碼如下:
~~~
???????? //文件名StaticVar.java
???????? public class StaticDemo{
?????????????????? static int m;
?????????????????? int n;
?????????????????? char c;
???????? }
???????? //文件名TestStaticVar.java
???????? public class TestStaticVar{
?????????????????? public static void main(String[] args){
??????????????????????????? StaticVar sv1 = new StaticVar();
??????????????????????????? StaticVar sv2 = new StaticVar();
?????????????????? }
???????? }
~~~
則對象sv1和對象sv2在內存中存儲的格式如下圖所示:
對象sv1????????????????????????????? 對象sv2
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">m</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">n</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">c</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">n</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">0</font></span></p></div></td></tr></tbody></table>
<table cellspacing="0" cellpadding="0" width="100%"><tbody><tr><td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"><div><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"><span lang="EN-US"><font face="Calibri" color="#000000" size="3">c</font></span></p></div></td></tr></tbody></table>
????????
對于StaticDemo類型的對象sv1和sv2來說,由于使用默認的構造方法進行構造,所以每個成員變量都被初始化為對應數據類型的默認值,int的默認值為0,char的默認值為編號為0的字符,所以sv1和sv2對象中存儲的值如上圖所示。
而靜態變量的存儲和非靜態變量的存儲不同,在Java虛擬機內部,第一次使用類時初始化該類中的所有靜態變量,以后就不再進行初始化,而且無論創建多少個該類的對象,靜態變量的存儲在內存中都是獨立于對象的,也就是Java虛擬機單獨為靜態變量分配存儲空間,所以導致所有的對象內部的靜態變量在內存中存儲時只有一個空間。這樣就導致使用任何一個對象對該值的修改都是使該存儲空間中的值發生改變,而其它對象在后續引用時就跟著發生了變化。靜態變量就是使用這樣的方式在所有的對象之間進行數值共享的。
靜態變量在實際使用時,可以通過只存儲一次來節約存儲空間,這個特性導致在類內部定義的成員常量一般都做成靜態的,因為常量的值在每個對象中都是相同的,而且使用static修飾也便于對成員常量的引用。
在類外部訪問某類中靜態變量(常量)的語法格式為:
類名.成員變量(常量)
例如:
StaticDemo.m
這樣方便對于成員變量的訪問。當然,語法上也不禁止使用:對象.成員變量,這樣的語法格式進行訪問,但是一般不推薦這樣使用,而且有些類是無法創建對象的。
注意:static關鍵字不能修飾成員方法或構造方法內部的變量。
##### 8.7.1.2 靜態方法
static修飾的方法稱作靜態方法。靜態方法和一般的成員方法相比,不同的地方有兩個:一是調用起來比較方便,二是靜態方法內部只能使用靜態的成員變量。所以一般靜態方法都是類內部的獨立的功能方法。例如為了方便方法的調用,Java API中的Math類中所有的方法都是靜態的,而一般類內部的static方法也是方便其它類對該方法的調用。
示例代碼如下:
~~~
?????????????????? //文件名MyMath.java
?????????????????? public class MyMath{
??????????????????????????? public static int max(int a,int b){
???????????????????????????????????? return (a > b ? a : b);
??????????????????????????? }
?????????????????? }
?????????????????? //文件名TestMyMath.java
?????????????????? public class TestMyMath{
??????????????????????????? public static void main(String[] args){
???????????????????????????????????? int m = 10;
???????????????????????????????????? int n = 20;
???????????????????????????????????? int k = MyMath.max(m,n);
??????????????????????????? }
?????????????????? }
~~~
靜態方法在類的外部進行調用時不需要創建對象,使用類名.方法名(參數)這樣的語法格式進行調研,簡化了代碼的編寫。
使用靜態方法時,需要特別注意的是靜態方法內部使用該類的非靜態成員變量,否則將出現語法錯誤。
靜態方法是類內部的一類特殊方法,只有在需要時才將對應的方法聲明成靜態的,一個類內部的方法一般都是非靜態的。
##### 8.7.1.3 靜態代碼塊
靜態代碼塊指位于類聲明的內部,方法和構造方法的外部,使用static修飾的代碼塊。靜態代碼塊在該類第一次被使用時執行一次,以后再也不執行。在實際的代碼中,如果需要對類進行初始化的代碼,可以寫在靜態代碼塊的內部。
示例代碼如下:
~~~
?????????????????? //文件名StaticBlock.java
?????????????????? public class StaticBlock{
??????????????????????????? static{
???????????????????????????????????? System.out.println(“靜態代碼塊!”);
??????????????????????????? }
?????????????????? }
~~~
靜態代碼塊是一種特殊的語法,熟悉該語法的特點,在實際程序中根據需要使用。
- 前言
- (1)序言
- (2)程序設計是什么?
- (3)你適合學習程序設計嗎?
- (4)如何學好程序設計?
- (5)程序設計介紹小結
- (6)計算機軟件基本概念
- (7)進制的概念
- (8)計算機內部的數據表達
- (9)網絡編程基礎
- (10)Java語言簡介
- (11)JDK的獲得、安裝和配置
- (12)第一個HelloWorld程序
- (13)Eclipse基本使用
- (14)Eclipse基礎使用進階
- (15)如何學好Java語法
- (16)代碼框架、關鍵字和標識符
- (17)基本數據類型
- (18)變量和常量
- (19)數據類型轉換
- (20)空白、語句結束和注釋
- (21)算術運算符
- (22)比較運算符
- (23)邏輯運算符
- (24)賦值運算符
- (25)位運算符
- (26)移位運算符
- (27)其它運算符
- (28)運算符優先級
- (29)表達式
- (30)流程控制基礎
- (31)if語句語法(1)
- (32)if語句語法(2)
- (33)if語句語法(3)
- (34)switch語句語法
- (35)while語句語法
- (36)do-while語句語法
- (37)for語句語法
- (38)break和continue語句
- (39)流程控制綜合示例1
- (40)流程控制綜合示例2
- (41)流程控制綜合示例3
- (42)流程控制綜合練習
- (43)數組概述
- (44)數組基礎語法
- (45)數組使用示例1
- (46)數組使用示例2
- (47)數組使用示例3
- (48)多維數組基礎
- (49)多維數組使用示例1
- (50)多維數組使用示例2
- (51)多維數組練習
- (52)方法聲明
- (53)方法聲明示例
- (54)方法調用
- (55)方法重載和參數傳遞
- (56)方法練習
- (57)面向對象基礎
- (58)類(一)
- (59)類(二)
- (60)對象
- (61)面向對象設計方法和面向對象特性(一)
- (62)繼承(二)
- (63)多態性
- (64)訪問控制符、修飾符和其它關鍵字
- (65)static修飾符
- (66)final修飾符
- (67)this和super
- (68)抽象類和接口(一)
- (69)抽象類和接口(二)
- (70)抽象類和接口(三)
- (71)內部類簡介
- (72)包的概念
- (73)JDK文檔使用
- (74)java.lang包介紹1
- (75)String類使用
- (76)StringBuffer類和System類
- (77)包裝類
- (78)時間和日期處理
- (79)Random隨機處理
- (80)集合框架簡述
- (81)異常處理概述
- (82)異常處理語法1
- (83)異常處理語法2
- (84)IO簡介
- (85)IO類體系
- (86)文件操作之File類使用
- (87)文件操作之讀取文件
- (88)文件操作之寫文件
- (89)讀取控制臺輸入
- (90)裝飾流使用1
- (91)裝飾流使用2
- (92)IO使用注意問題
- (93)多線程基礎
- (94)多線程實現方式1
- (95)多線程實現方式2
- (96)多線程使用示例1
- (97)多線程使用示例2
- (98)多線程問題及處理1
- (99)多線程問題及處理2
- (100)多線程問題及處理3
- (101)網絡編程概述
- (102)網絡編程技術1
- (103)網絡編程技術2
- (104)網絡編程技術3
- (105)網絡編程技術4
- (106)網絡編程技術5
- (107)網絡協議概念
- (108)網絡編程示例1
- (109)網絡編程示例2
- (110)網絡編程小結