天天看點

對java中public、static的了解

首先是public 

在說明這四個關鍵字之前,我想就class之間的關系做一個簡單的定義,對于繼承自己的class,base class可以認為他們都是自己的子女,而對于和自己一個目錄下的classes,認為都是自己的朋友。

1、public:public表明該資料成員、成員函數是對所有使用者開放的,所有使用者都可以直接進行調用

2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用,私有财産神聖不可侵犯嘛,即便是子女,朋友,都不可以使用。

3、protected:protected對于子女、朋友來說,就是public的,可以自由使用,沒有任何限制,而對于其他的外部class,protected就變成private。

作用域 目前類 同一package 子孫類 其他package 

public       √             √                √               √ 

protected √             √                √                × 

friendly     √             √                ×               × 

private     √              ×               ×                ×

不寫時預設為friendly

然後是static

static在java中表示靜态

但是這個靜态又是什麼意思呢?

最開始接觸static的時候看書上的概念根本沒弄懂!

接觸有一段時間java了,在這裡面要總結一下我對static的了解:

(概念)static表示“全局”或者“靜态”的意思,用來修飾成員變量和成員方法,也可以形成靜态static代碼塊,但是Java語言中沒有全局變量的概念。

這句話是說,你會用到static修飾一些個變量、方法、方法塊什麼的,這是你用到static的地方;“但是,java中沒有全局變量的概念”,怎麼了解這句話?你時刻要記住java是一個面向對象的語言,萬事萬物皆對象,無論你做什麼都需要建立一個對象,然後再調用這個對象的方法,java怎麼能允許存在一個在全局都通用的“全局變量”的概念存在呢?是以java中壓根就沒有所謂的“全局變量”,但是沒有這個概念,不代表你不可以實作這個功能,java存在的目的就是讓人們使用它去達到人們想要的效果,是以static value就可以達到全局變量的作用,是以,你現在應該可以了解下面這句話了吧。

(概念)用public修飾的static成員變量和成員方法本質是全局變量和全局方法,當聲明它類的對象市,不生成static變量的副本,而是類的所有執行個體共享同一個static變量。

現在進一步了解下面兩段概念:

(概念)隻要這個類被加載,Java虛拟機就能根據類名在運作時資料區的方法區内找到他們。是以,static對象可以在它的任何對象建立之前通路,無需引用任何對象。

根據實際例子來了解這段概念,現在有兩個類,Demo1和Demo2。

此執行個體還包含對靜态方法的操作

public class Demo1 {

    public static int i = 1;

    public int j = 2;

    public static int getNumber(){

        return i;

//        這個return傳回的是全局變量的i,即前面多建立的i

    }

    public int getDealNumber(int j){

        return j;

//        這個return傳回的是所傳進來的參數,是(int j)這個東西

    }

}

public class Demo2 {

    public static void main(String args[]){

//        想要得到Demo1中的靜态的(即全局的)變量i,直接用類名引用就可以了

        int i = Demo1.i;

//        但是想要得到Demo1中的執行個體的變量j,我需要怎麼做呢?(此刻牢記java面向對象的思想!)

//        首先我要先new一個Demo1的對象,然後才可以通過new出來的對象得到Demo1中的j

        Demo1 demo1 = new Demo1();

        int j = demo1.j;

//        同理,java中的static方法和非static方法都是一樣的差別

//        下面一行的方法是靜态的,我可以直接根據類名調用方法

        int ii = Demo1.getNumber();

//        但是想要調用執行個體的方法,就需要利用前面所new出來的Demo1的對象來調用了

        int jj = demo1.getDealNumber(1);

//        是以現在你可以了解上文紫色的定義了麼?

    }

}

(概念)用public修飾的static成員變量和成員方法本質是全局變量和全局方法,當聲明它類的對象市,不生成static變量的副本,而是類的所有執行個體共享同一個static變量。

弄懂了上面的代碼,這句定義是不是迎刃而解了呢?這裡面涉及到堆棧的問題,我現在還沒有整理,我會整理的,寫完這篇我馬上就要鞏固一下堆棧的知識,我認為堆棧的知識很重要,如果你也是初學者,關注我吧,嘿嘿~

這裡說一下靜态變量和執行個體變量的差別:

兩者的差別是:

 對于靜态變量在記憶體中隻有一個拷貝(節省記憶體),JVM隻為靜态配置設定一次記憶體,在加載類的過程中完成靜态變量的記憶體配置設定,可用類名直接通路(友善),當然也可以通過對象來通路(但是這是不推薦的)。

 對于執行個體變量,沒建立一個執行個體,就會為執行個體變量配置設定一次記憶體,執行個體變量可以在記憶體中有多個拷貝,互不影響(靈活)。

是以一般在需要實作以下兩個功能時使用靜态變量:

在對象之間共享值時

 友善通路變量時

現在了解一下靜态方法

2、靜态方法

靜态方法可以直接通過類名調用,任何的執行個體也都可以調用靜态方法。前面的代碼中有直接通過類名調用的例子

靜态方法中不能用this和super關鍵字,不能直接通路所屬類的執行個體變量和執行個體方法(就是不帶static的成員變量和成員成員方法),隻能通路所屬類的靜态成員變量和成員方法。因為執行個體成員與特定的對象關聯!就是java面向對象的思想,執行個體是你這個類本身的屬性,你會用這個本身的屬性去做一些事情,而這些事情不是固定的,不能像靜态方法一樣一成不變。換位思考,人是一個java類,手是類的執行個體方法,而人身上有手機,這個手機就是靜态方法;人隻會用手去玩手機,你見過人用手機玩手麼?哈哈

因為static方法獨立于任何執行個體,是以static方法必須被實作,而不能是抽象的abstract。靜态方法是類内部的一類特殊方法,隻有在需要時才将對應的方法聲明成靜态的,一個類内部的方法一般都是非靜态的

怎麼了解上面這句定義呢?記住得了,哈哈。

3、static代碼塊

 static代碼塊也叫靜态代碼塊,是在類中獨立于類成員的static語句塊,可以有多個,位置可以随便放,它不在任何的方法體内,JVM加載類時會執行這些靜态的代碼塊,如果static代碼塊有多個,JVM将按照它們在類中出現的先後順序依次執行它們,每個代碼塊隻會被執行一次。例如:

public class Test5 {

private static int a;

private int b;

static{

Test5.a=3;

System.out.println(a);

Test5 t=new Test5();

t.f();

t.b=1000;

System.out.println(t.b);

}

static{

Test5.a=4;

System.out.println(a);

}

public static void main(String[] args) {

// TODO 自動生成方法存根

}

static{

Test5.a=5;

System.out.println(a);

}

public void f(){

System.out.println("hhahhahah");

}

}  

運作結果:

3

hhahhahah

1000

4

5

 利用靜态代碼塊可以對一些static變量進行指派,最後再看一眼這些例子,都一個static的main方法,這樣JVM在運作main方法的時候可以直接調用而不用建立執行個體。

還用我再說什麼麼?

有時你希望定義一個類成員,使它的使用完全獨立于該類的任何對象。通常情況下,類成員必須通過它的類的對象通路,但是可以建立這樣一個成員,它能夠被它自己使用,而不必引用特定的執行個體。在成員的聲明前面加上關鍵字static(靜态的)就能建立這樣的成員。如果一個成員被聲明為static,它就能夠在它的類的任何對象建立之前被通路,而不必引用任何對象。你可以将方法和變量都聲明為static。static 成員的最常見的例子是main( ) 。因為在程式開始執行時必須調用main() ,是以它被聲明為static。

如果讀不懂這句話就倒着念,就明白個大概了。

注意一下幾點

聲明為static的變量實質上就是全局變量。當聲明一個對象時,并不産生static變量的拷貝,而是該類所有的執行個體變量共用同一個static變量。聲明為static的方法有以下幾條限制:

它們僅能調用其他的static 方法。

它們隻能通路static資料。

它們不能以任何方式引用this 或super(關鍵字super 與繼承有關,在下一章中描述)。

如果你需要通過計算來初始化你的static變量,你可以聲明一個static塊,Static 塊僅在該類被加載時執行一次。

下面的例子顯示的類有一個static方法,一些static變量,以及一個static 初始化塊:

// Demonstrate static variables,methods,and blocks.

class UseStatic {

static int a = 3;

static int b;

static void meth(int x) {

System.out.println("x = " + x);

System.out.println("a = " + a);

System.out.println("b = " + b);

}

static {

System.out.println("Static block initialized.");

b = a * 4;

}

public static void main(String args[]) {

meth(42);

}

}

一旦UseStatic 類被裝載,所有的static語句被運作。首先,a被設定為3,接着static 塊執行(列印一條消息),最後,b被初始化為a*4 或12。然後調用main(),main() 調用meth() ,把值42傳遞給x。3個println ( ) 語句引用兩個static變量a和b,以及局部變量x 。

注意:在一個static 方法中引用任何執行個體變量都是非法的。