程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java關鍵字介紹之static

Java關鍵字介紹之static

編輯:關於JAVA

1.關鍵字static(先記住這些,再往下看)

1)靜態方法和靜態變量是屬於某一個類,而不屬於類的對象。

2)靜態方法和靜態變量的引用直接通過類名引用。

3)在靜態方法中不能調用非靜態的方法和引用非靜態的成員變量。反之,則可以。

4)靜態變量在某種程序上與其他語言的全局變量相類似,如果不是私有的就可以在類的外部進行訪問。

2.何時使用static

在我們創建一個類的實例時(對象),通常使用new方法,這樣這個類的數據空間才會被創建,其方法才能被調用。

但是,有時候我們希望一個類雖然可以被創建n個對象(顯然這n個對象的數據空間是不相同的),但這n個對象的某些數據是相同的,即不管這個類有多少的實例,這些數據對這些實例而言之有一份內存拷貝(見示例1)。這是靜態變量的情形。

另一種情形是,你希望某個方法不與包含它的類的任何對象關聯在一起。也就是說,即使沒有創建對象,也能夠調用這個方法。static 方法的一個重要用法就是在不創建任何對象的前提下,就可以調用它(見示例2)。這是靜態方法的情形。

還有一種特殊的用法出現在內部類中,通常一個普通類不允許聲明為靜態的,只有一個內部類才可以。這時這個聲明為靜態的內部類可以直接作為一個普通類來使用,而不需實例一個外部類(見示例3)。這是靜態類的情形。

示例1

public class TStatic {
static int i;
public TStatic() {
i = 4;
}
public TStatic(int j) {
i = j;
}
public static void main(String args[]) {
System.out.println(TStatic.i);
TStatic t = new TStatic(5); // 聲明對象引用,並實例化。此時i=5
System.out.println(t.i);
TStatic tt = new TStatic(); // 聲明對象引用,並實例化。此時i=4
System.out.println(t.i);
System.out.println(tt.i);
System.out.println(t.i);
}
}

結果:

0

5

4

4

4

static變量在類被載入時創建,只要類存在,static變量就存在。它們在定義時必須進行初始化。上例中沒有初始化i,所以會得到默認的初始值0。static的變量的初始化僅能一次,static變量只是接受了最後一次的初始化。

實際這還是多個實例共享一個靜態的變量的問題。

示例2

未聲明為static

class ClassA {
int b;
public void ex1() {}
class ClassB {
void ex2() {
int i;
ClassA a = new ClassA();
i = a.b; // 這裡通過對象引用訪問成員變量b
a.ex1(); // 這裡通過對象引用訪問成員函數ex1
}
}
}

聲明為static

class ClassA {
static int b;
static void ex1() {}
}
class ClassB {
void ex2() {
int i;
i = ClassA.b; // 這裡通過類名訪問成員變量b
ClassA.ex1(); // 這裡通過類名訪問成員函數ex1
}
}

在使用靜態方法時要注意,在靜態方法中不能調用非靜態的方法和引用非靜態的成員變量(在static方法中也不能以任何方式引用this或super)。理由很簡單,對於靜態的東西,JVM在加載類時,就在內存中開辟了這些靜態的空間(所以可以直接通過類名引用),而此時非靜態的方法和成員變量所在的類還沒有實例化。

所以如果要使用非靜態的方法和成員變量,可以直接在靜態方法中實例化該方法或成員變量所在的類。public static void main就是這麼干的。

示例3

public class StaticCls {
public static void main(String[] args) {
OuterCls.InnerCls oi = new OuterCls.InnerCls();// 這之前不需要new一個OuterCls
}
}
class OuterCls {
public static class InnerCls {
InnerCls() {
System.out.println("InnerCls");
}
}
}

結果:

InnerCls

3.靜態初始化

static定義的變量會優先於任何其它非static變量,不論其出現的順序如何。靜態代碼塊(在“static{”後面跟著一段代碼),是用來進行顯式的靜態變量初始化,這段代碼只會初始化一次,且在類被第一次裝載時。看下面示例。

class Value {
static int c = 0;
Value() {
c = 15;
}
Value(int i) {
c = i;
}
static void inc() {
c++;
}
}
class Count {
public static void prt(String s) {
System.out.println(s);
}
Value v = new Value(10);
static Value v1, v2;
static {
prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
+ v2.c);
v1 = new Value(27);
prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
+ v2.c);
v2 = new Value();
prt("in the static block of calss Count v1.c=" + v1.c + " v2.c="
+ v2.c);
}
}
public class TStaticBlock {
public static void main(String[] args) {
Count ct = new Count();
Count.prt("in the main:");
Count.prt("ct.c=" + ct.v.c);
Count.prt("v1.c=" + Count.v1.c + " v2.c=" + Count.v2.c);
Count.v1.inc();
Count.prt("v1.c=" + Count.v1.c + " v2.c=" + Count.v2.c);
Count.prt("ct.c=" + ct.v.c);
}
}

結果:

in the static block of calss Count v1.c=0 v2.c=0

in the static block of calss Count v1.c=27 v2.c=27

in the static block of calss Count v1.c=15 v2.c=15

in the main:

ct.c=10

v1.c=10 v2.c=10

v1.c=11 v2.c=11

ct.c=11

不管是v,v1還是v2,它們操作的成員變量都是同一個靜態變量c。

在類Count中先初始化v1,v2(static Value v1, v2;),再初始化靜態代碼塊(static{}),最後初始化v。

author: ZJ 2007-3-10

Blog: http://zhangjunhd.blog.51cto.com/

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved