1. 程式人生 > >關於Java關鍵字static與final一些總結

關於Java關鍵字static與final一些總結

前幾天去面試,突然被問到Java關鍵字中的static和final,有點懵逼,有些概念性的東西竟然忘了,痛定思痛,故打算這樣一篇部落格來複習一下。

一、static

靜態修飾符,可作用在變數、方法,方法塊,類(內部類),所對應的呼叫時機和呼叫次數有所不同,主要分為以下幾種情況:

1、作用在變數和方法塊

public class ClassE {
	static int a = 1;
	static{
		System.out.println("ClassE靜態程式碼塊");
	}
	public ClassE() {
		System.out.println("ClassE構造");
	}
	public static void main(String[] args) {
		ClassE classE = new ClassE();
		ClassE classE2 = new ClassE();
	}
}

執行結果:

ClassE靜態方法塊
ClassE構造

ClassE構造

初始化一個類時,首先按程式碼順序,初始化類中的靜態變數和執行類中的靜態程式碼塊,然後在呼叫構造方法。但是應該注意的是,靜態變數的初始化和靜態程式碼塊的執行,只會在第一次呼叫該類時執行僅有的一次!!

此外,如果呼叫類中的靜態方法,也會先執行該類中所有靜態變數的初始化和靜態程式碼塊後,再呼叫該靜態方法,也是隻會在第一次呼叫該類時執行僅有的一次(不管呼叫該類中任意一靜態方法,都只會在第一次呼叫時執行且只會執行一次),例如:

public class ClassE {
	static int a = 1;
	static{
		System.out.println("ClassE靜態方法塊");
	}
	public ClassE() {
		System.out.println("ClassE構造");
	}
	static void fun1(){
		System.out.println("呼叫靜態方法1");
	}
	static void fun2(){
		System.out.println("呼叫靜態方法2");
	}
	public static void main(String[] args) {
		ClassE.fun1();
		ClassE.fun2();
	}
}

執行結果:

ClassE靜態方法塊
呼叫靜態方法1

呼叫靜態方法2

注意:不管靜態還是非靜態的變數都可以被子類繼承和覆蓋(即父類中定義一個靜態變數,可以通過子類進行呼叫)。

public class ClassB {
	static int a = 1;
}
public class ClassA extends ClassB {
	public static void main(String[] args) {
		int z = ClassA.a;//合法操作
	}
}

如果在子類中重寫該靜態變數,父類中該靜態變數就會被隱藏。

2、作用在方法

靜態方法,只要定義了類,不必建立類的例項就可使用。

public class ClassE {
	
	public ClassE() {
		
	}
	static void fun1(){
		System.out.println("呼叫靜態方法1");
	}
	void fun2(){
		System.out.println("呼叫非靜態方法2");
	}
	public static void main(String[] args) {
		ClassE.fun1();
		ClassE classE = new ClassE();
		classE.fun2();
	}
}

靜態方法的繼承與靜態變數的繼承一致,可參照靜態變數的做法進行操作。注意,靜態方法中無法使用super關鍵字,所有有關於super關鍵字的一切操作都無實現。

3、靜態內部類

關鍵字static不能修飾外部類,只能修飾內部類。

public class ClassD {
    static class ClassE{
	public ClassE() {
	    System.out.println("靜態類構造方法");
	}
	void fun(){
             System.out.println("靜態類構造方法");
        }
    }
    public static void main(String[] args) {
    ClassE classE = new ClassE();classE.fun();
    }
}

靜態內部類的作用:為了降低包的深度,方便類的使用,靜態內部類適用於包含類當中,但又不依賴與外在的類,只是為了方便管理類結構而定義。在建立靜態內部類的時候,不需要外部類物件的引用。

靜態內部類和非靜態內部類區別:非靜態內部類可以呼叫外部類變數,靜態內部類不可以呼叫外部類非靜態變數。

4、靜態關鍵字Static對類初始化時呼叫程式碼順序的影響

子Class繼承含有static關鍵字父Class,構造子Class物件時,程式碼的執行順序:

//父類
public class ClassI {
	static int a = 1;//靜態變數
	int b = 1;//全域性變數
	static{
		System.out.println("父類的靜態程式碼塊");
	}
	public ClassI() {
		System.out.println("父類的構造方法");
	}
}
//子類
public class ClassH extends ClassI{
	static int c = 1;
	int d = 1;//全域性變數
	static{
		System.out.println("子類的靜態程式碼塊");
	}
	public ClassH() {
		System.out.println("子類的構造方法");
	}
	public static void main(String[] args) {
		ClassH classH = new ClassH();
	}
}

父類的靜態物件->子類的靜態物件->父類全域性變數宣告和初始化->父類的建構函式->子類全域性變數宣告和初始化->子類的建構函式

二、Final

該關鍵字用於表明不可修改或者不可繼承。可以作用於變數,方法,類

1、作用在類上面說明該類不可被繼承

2、作用在方法上,說明在繼承該類的子類不可修改該方法。

3、作用在變數上,說明該變數不可變(注意:在定義final型別的變數時,需要初始化該值,否則會報錯)

關鍵字final對程式碼的呼叫順序沒有影響,用法也比關鍵字static簡單。