1. 程式人生 > >第九天(上) final和static關鍵字

第九天(上) final和static關鍵字

結果 需要 println 使用 trac 非靜態變量 地理 成員變量 tex

繼承的出現提高了代碼的復用性,方便開發,是多態的前提,但隨之而來的也有問題,有些累在描述後不想被繼承,或者裏面的方法功能時固定的,不想讓子類重寫,可子類繼承之後又可以重寫該怎麽辦呢

這個時候就需要一個關鍵字final 意為 最終的 不可變的

Final是一個比較強的修飾符,可以用來修飾類,類的成員,以及方法

Final修飾類

在類的前面加上final

Final類不可以被繼承,但可以繼承其他類,是個太監.其成員方法也默認為final的,但成員變量是可以改變的

在使用final修飾類的時候,要註意謹慎選擇,除非這個類真的在以後不會用來繼承或者出於安全的考慮,盡量不要將類設計為final類。

Final修飾方法

l 子類可以繼承final修飾的方法,但不能重寫.

l 父類中沒有被final修飾的方法,子類繼承後可以用final修飾

l 如果父類中final修飾的方法同時訪問控制權限為private將會導致子類中不能直接繼承到此方法,因此,此時可以在子類中定義相同的方法名和參數,此時不再產生重寫與final的矛盾,而是在子類中重新定義了新的方法

註:類的private方法會隱式地被指定為final方法。

Final修飾局部變量:

修飾基本數據類型

Final修飾的變量稱為常量,只能賦值一次,就不會被改變即使賦的新值與舊值一樣也不可以。

修飾引用數據類型

引用數據類型的值是地址值,final修飾後不可以改變地址值

,但地址值所指的內容是可以改變的.

Final修飾成員變量

修飾成員變量時,成員變量需要在創建對象前復制

1直接賦值 通過等號

2構造方法中賦值 沒有顯式的賦值那麽多個構造方法都要為其賦值

Final修飾成員變量時,固定的不是內存中的值,而是手動的賦值(成員變量是有默認值的)

Final修飾方法參數

有點懵比,查了好多沒有找到一個令人信服的,說法也不一樣

關於final的一些題

public class Test {

public static void main(String[] args) {

String a = "hello2";

final String b = "hello";

String d = "hello";

String c = b + 2;

String e = d + 2;

System.out.println((a == c));

System.out.println((a == e));

System.out.println(a.equals(e));

}

}

結果true

false

True

為什麽呢?

b被聲明成了final的了,所以就是常量,常量表達式String c = b + 2;JVM會優化成String c = "hello" + 2;,這個結果是變成編譯期就是已知了,指向常量池中的hello2字符串,也就是a

public class Test {

public static void main(String[] args) {

String a = "hello2";

final String b = getHello();

String c = b + 2;

System.out.println((a == c));

}

public static String getHello() {

return "hello";

}

}

結果:
false

這裏的b雖然是常量,但是在編譯期是不能獲得值的,只有在運行的時候才會調用函數,初始化賦值,所以這時的String c = b+2是運行期間計算出來的,而加號連接運算符,內部則是調用的StringBuilder,然後toString,所以c相當於是new出來的String,即c是指向堆內存的地址,c內部的char數組才指向常量池中的字符串,所以明顯a != c.

希望看了深入理解jvm虛擬機後可以更好的理解這些問題.

Static

定義類的時候,類中會有相應的方法和屬性,而方法和屬性都是通過創建本類對象調用的,當調用對象的某個方法時,這個方法又沒有訪問特定的數據,創建這個對戲那個就有點多余,或者說沒有對象都有一模一樣的常量,每new一個就出現一次這個常量,又沒有辦法一勞永逸呢

要解決上面的問題就要用到關鍵字static.

代表全局,靜態的意思,用來修飾成員變量,成員方法,以及代碼塊.其次還有靜態內部類以後有機會了解.

Static的作用: 簡單來說就是方便在沒有創建對象的情況下來調用方法或者變量.

Java中並不存在全局變量的概念,但我們可以用static來實現一個偽全局變量的概念,

Static修飾變量:被static修飾(只能修飾成員變量)變量稱為靜態變量,沒有使用static修飾的叫實例變量.伴隨著類的加載完成初始化.分配一次內存.每一個對象對靜態變量的操作都會反應到其他對象上。

什麽時候該使用static修飾呢?

當這個成員會被類的所有對象所共享,一般我們把共性的數據定義為靜態變量

有什麽好處呢

對象之間共享數據,訪問方便,節約內存

怎麽調用呢

類名.靜態成員變量名

對象名.靜態成員變量名 ------不建議使用該方式,會出現警告

Static修飾方法:static修飾的方法稱為靜態方法.

他在類加載的時候就存在了,它不依賴於任何實例,所以static方法必須實現,也就是說他不能是抽象方法abstract。

什麽時候該使用static修飾

成員方法跟著變量走,靜態方法只能訪問靜態變量,如果成員方法中引用了靜態的其他成員,那麽這個方法就要聲明為靜態的方法.

怎麽調用

類名.靜態成員方法名(參數)

對象名.靜態成員方法名(參數) ------不建議使用該方式,會出現警告

註意事項:

靜態方法不能操作非靜態變量,也不能調用非靜態方法。(這個可以這樣理解:靜態方法屬於類,直接通過類名就可以調用,而此時可能沒有任何實例,更談不上操作實例變量和調用實例方法了。)

同理,靜態也不能使用this和super關鍵字.

所以main方法中不能直接調用非靜態的方法.

為什麽mian方法時靜態的

為了使在調用mian方法前不創建任何實例對象.

Static靜態代碼塊

static修飾的代碼塊,我們稱之為靜態代碼塊,靜態代碼塊會隨著類的加載一塊執行,而且他可以隨意放,可以存在於該了的任何地方。

用來初始化靜態變量。

在類加載時,在執行main方法之前執行相關操作。

沒有main方法的程序可以執行嗎?

Jdk1.7之前可以

之後會報錯

靜態導包

感覺沒什麽用jdk1.5之後

其目的是為了減少字符輸入量,提高代碼的可閱讀性,以便更好地理解程序。

采用static導入包後,在不與當前類的方法名沖突的情況下,無需使用“類名.方法名”的方法去調用類方法了,直接可以采用"方法名"去調用類方法,就好像是該類自己的方法一樣使用即可。

建議對於靜態導入,一定要遵循兩個規則:

1.不要使用*(星號)通配符,除非是導入靜態常量(只包含常量的類或接口)。

2. 方法名是具有明確、清晰表象意義的工具類。

靜態內部類

內部類了解


第九天(上) final和static關鍵字