1. 程式人生 > >Java中如何理解Static,Final,Static Final

Java中如何理解Static,Final,Static Final



Static

為什麼要用static?

有一些頻繁使用的東西,如果你每次使用都重新new一下,那麼這個開銷可能會很高,如果使用static,一直放在記憶體中,那麼想用就直接用,而不需要重新new一塊空間初始化資料。那麼static就是為了實現一個系統的快取作用的,其生命週期直到應用程式退出結束。

這說明,static修飾的類成員,在程式執行過程中,只需要初始化一次即可,不會進行多次的初始化。

主要有四種用法:

1.用來修飾成員變數,將其變為類的成員,從而實現所有物件對於該成員的共享;

2.用來修飾成員方法,將其變為類方法,可以直接使用“類名.方法名”的方式呼叫,常用於工具類;

3.

靜態塊用法,將多個類成員放在一起初始化,使得程式更加規整,其中理解物件的初始化過程非常關鍵;

4.靜態導包用法,將類的方法直接匯入到當前類中,從而直接使用“方法名”即可呼叫類方法,更加方便。

static可以修飾:方法,屬性,程式碼段,內部類(靜態內部類或巢狀內部類)

static成員變數

靜態變數和非靜態變數的區別是:

靜態變數被所有的物件所共享,在記憶體中只有一個副本,它當且僅當在類初次載入時會被初始化。

非靜態變數是物件所擁有的,在建立物件的時候被初始化,存在多個副本,各個物件擁有的副本互不影響。

static是不允許用來修飾區域性變數

static方法

首先,在靜態方法中不能訪問類的非靜態成員變數和非靜態成員方法。

原因:非靜態成員(變數和方法)屬於類的物件,所以只有在類的物件產生(建立類的例項)時才會分配記憶體,然後通過類的物件(例項)去訪問。在一個類的靜態成員中去訪問其非靜態成員之所以會出錯是因為在類的非靜態成員不存在的時候類的靜態成員就已經存在了,訪問一個記憶體中不存在的東西當然會出錯。

其次,即使沒有顯示地宣告為static,類的構造器實際上也是靜態方法。

static程式碼塊

static塊可以用來優化程式效能,是因為它的特性:只會在類載入的時候執行一次。

很多時候會將一些只需要進行一次的初始化操作都放在static程式碼塊中進行。

static內部類

static內部類與非

static內部類的區別:首先,在非靜態內部類中不可以宣告靜態成員。

其次,靜態內部類不能訪問其外部類的非靜態成員變數和方法。最後在建立靜態類內部物件時,不需要其外部類的物件。java在實現LinkedList時使用瞭如下內部類:public class LinkedList<E>
extendsAbstractSequentialList<E>
implements List<E>,Deque<E>, Cloneable, java.io.Serializable
{
........
private static classEntry<E> {
E element;
Entry<E> next;
Entry<E> previous;
Entry(E element,Entry<E> next, Entry<E> previous) {
this.element =element;
this.next = next;
this.previous =previous;
}
}
private Entry<E> addBefore(E e,Entry<E> entry) {
Entry<E> newEntry =new Entry<E>(e, entry, entry.previous);
newEntry.previous.next = newEntry;
newEntry.next.previous =newEntry;
size++;
modCount++;
return newEntry;
}
........
}
這裡即靜態內部類的典型用法

如果想要更深入的瞭解

final

主要用法有以下四種:

1.用來修飾資料,包括成員變數和區域性變數,該變數只能被賦值一次且它的值無法被改變。對於成員變數來講,我們必須在宣告時或者構造方法中對它賦值;

2.用來修飾方法引數,表示在變數的生存期中它的值不能被改變;

3.修飾方法,表示該方法無法被重寫;

4.修飾類,表示該類無法被繼承。

上面的四種方法中,第三種和第四種方法需要謹慎使用,因為在大多數情況下,如果是僅僅為了一點設計上的考慮,我們並不需要使用final來修飾方法和類。

final可以修飾:屬性,方法,類,區域性變數(方法中的變數)

final資料(成員變數和區域性變數)

  • 首先,用final關鍵字修飾的變數,只能進行一次賦值操作,並且在生存期內不可以改變它的值。

  • 其次,編譯器在編譯時期就對該資料進行替換甚至執行計算。可以先宣告,後賦值。

  • 然後,final修飾的成員變數,我們有且只有兩個地方可以給它賦值,一個是宣告該成員時賦值,另一個是在構造方法中賦值,在這兩個地方我們必須給它們賦初始值。

  • 再者,基本型別和引用型別時,final關鍵字的效果存在細微差別。final修飾引用變數時,限定了引用變數的引用不可改變,但是引用的物件的值是可以改變的。

final方法

表示該方法不能被覆蓋,但是能被繼承。

final

final修飾的類是無法被繼承的。

Static final

同時使用staticfinal修飾的成員在記憶體中只佔據一段不能改變的儲存空間。

附:成員變數與區域性變數的區別

  • 在類中位置不同。成員變數:在類中方法外。區域性變數:在方法定義中或者方法宣告上。

  • 在記憶體中的位置不同。成員變數:在堆記憶體。區域性變數:在棧記憶體。

  • 生命週期不同。成員變數:隨著物件的建立而存在,隨著物件的消失而消失。區域性變數:隨著方法的呼叫而存在,隨著方法的呼叫完畢而消失。

  • 初始化值不同。成員變數:有預設值初始化。區域性變數:沒有預設值初始化,必須定義,賦值,然後才能使用。

  • 另外,區域性變數名稱可以和成員變數名稱一樣,在方法中使用的時候,採用的是就近原則。