搜尋
首頁Javajava教程static關鍵字有什麼作用

static關鍵字有什麼作用

Aug 21, 2019 pm 03:41 PM
java

今天主要學習下Java語言中的static關鍵字。

static關鍵字有什麼作用

static關鍵字的意義及使用場景

static是Java50個關鍵字之一。 static關鍵字可以用來修飾程式碼區塊表示靜態程式碼區塊,修飾成員變數表示全域靜態成員變量,修飾方法表示靜態方法。 (注意:不能修飾普通類,除了內部類,這是為什麼?)

class A {
	static {
		System.out.println("A : 静态代码块");
	}
	
	static int i ;  // 静态变量
	
	static void method() {
		System.out.println("A: 静态方法");
	}
}

簡而言之,被static關鍵字修飾的內容都是靜態的。

靜態是相對於動態的,動態是指Java程式在JVM上執行時,JVM會根據程式的需要動態建立物件並儲存物件(分配記憶體),物件使命結束後,物件會被垃圾回收器銷毀,即記憶體回收由JVM統一管理並分配給其他新建立的物件;靜態是指Java程式還沒運作時,JVM就會為載入的類別分配空間儲存被static關鍵字修飾的內容;如靜態成員變量,Java類別載入到JVM中,JVM會把類別以及類別的靜態成員變數儲存在方法區,我們知道方法區是執行緒共享且很少發生GC的區域,所以被static關鍵字修飾的內容都是全域共享的,且只會為其分配一次儲存空間。

所以當類別的某些內容不屬於對象,而由物件共用即屬於類別的時候,就可以考慮是否要用static關鍵字修飾。

static關鍵字的作用

1 修飾程式碼區塊

類別中用static關鍵字修飾的程式碼區塊稱為靜態程式碼,反之沒有用static關鍵字修飾的程式碼區塊稱為實例程式碼區塊。

實例程式碼區塊會隨著物件的創建而執行,也就是每個物件都會有自己的實例程式碼區塊,表現出來就是實例程式碼區塊的運行結果會影響目前物件的內容,並且隨著物件的銷毀而消失(記憶體回收);而靜態程式碼區塊是當Java類別載入到JVM記憶體中而執行的程式碼區塊,由於類別的載入在JVM運作期間只會發生一次,所以靜態程式碼區塊也只會執行一次。

因為靜態程式碼區塊的主要作用是用來進行一些複雜的初始化工作,所以靜態程式碼區塊跟隨類別儲存在方法區的表現形式是靜態程式碼區塊執行的結果儲存在方法區,也就是初始化量儲存在方法區並被執行緒共用。

2 修飾成員變數

類別中用static關鍵字修飾的成員變數稱為靜態成員變量,因為static無法修飾局部變數(為什麼?),因此靜態成員變數也能稱為靜態變數。靜態變數跟程式碼區塊類似,在類別載入到JVM記憶體中,JVM會把靜態變數放入方法區並分配內存,也由執行緒共享。存取形式是:類別名稱.靜態成員名。

public class StaticTest {
	public static void main(String[] args) {
		System.out.println(D.i);
		System.out.println(new D().i);
	}
}
class D {
	static {
		i = 2;
		System.out.println("D : 静态代码块1");
	}
	static int i;
}

靜態變數儲存在類別的資訊中,且可以在線程間共享,那麼它當然也屬於該類別的每個對象,因此可以透過對象存取靜態變量,但編譯器並不支援這麼做,且會給予警告。

注意:

一個類別的靜態變數和該類別的靜態程式碼區塊的載入順序。類別會優先載入靜態變量,然後載入靜態程式碼區塊,但有多個靜態變數和多個程式碼區塊時,會按照編寫的順序進行載入。

class D {
	static {
		i = 2;
		System.out.println("D : 静态代码块1");
	}
	static {
		i = 6;
		System.out.println("D : 静态代码块2");
	}
	static int i;
}

可以想一下運行的結果。

靜態變數可以不用明確的初始化,JVM會預設給其對應的預設值。如基本資料型別的byte為0,short為0,char為\u0000,int為0,long為0L,float為0.0f,double為0.0d,boolean為false,引用型別為null。

靜態變數既然是JVM記憶體中共享的且可以改變,那麼對它的存取會引起線程安全問題(線程A改寫的同時,線程B取得它的值,那麼獲取的是修改前的值還是修改後的值呢?),所以使用靜態變數的同時要考慮多執行緒情況。如果能確保靜態變數不可變,那麼可以用final關鍵字一起使用避免線程安全問題;否則需要採用同步的方式避免線程安全問題,例如與volatile關鍵字一起使用等。

static關鍵無法修飾局部變量,包括實例方法和靜態方法,不然就會與static關鍵字的初衷-共享相違背。

3 修飾方法

用static關鍵字修飾的方法稱為靜態方法,否則稱為實例方法。透過類別名稱.方法名稱調用,但需要注意靜態方法可以直接調用類別的靜態變數和其他靜態方法,不能直接調用成員變數和實例方法(除非透過物件調用)。

class D {
	static {
		i = 2;
		System.out.println("D : 静态代码块");
	}
	static final int i;
	int j;
	
	static void method() {
		System.out.println(i);
		System.out.println(new D().j);
		
		method1();
		new D().method2();
	}
	
	static void method1() {
		System.out.println(i);
	}
	void method2() {
		System.out.println(i);
	}
}

注意:既然類別的實例方法需要物件呼叫才能訪問,而靜態方法直接透過類別名稱就能訪問,那麼在不考慮部署伺服器的情況下,一個類別是如何開始執行的呢?最大的可能就是透過「類別名稱.靜態方法」啟動Java,而我定義那麼多靜態方法,JVM又是如何知道主入口呢?

或許,你想到了main方法。

沒錯,就是main方法被Java規格定義成Java類別的主入口。 Java類別的運行都由main方法開啟:

 public static void main(String[] args) {
	for (String arg : args) {   // 参数由外部定义
		System.out.println(arg);
	}}

但注意main并不是Java关键字,它只是一个规定的程序入口的方法名字;另外main方法可以重载。

注意:static关键字虽然不能修饰普通类,但可以用static关键字修饰内部类使其变成静态内部类。static关键字本身的含义就是共享,而Java类加载到JVM内存的方法区,也是线程共享的,所以没必要用static关键字修饰普通类。

4 静态导入

在用import导入包或者类时,可以用static修饰包名或者类,表示静态导入。静态导入可以与动态导入放在一起比较来加深理解。

动态导入是当你程序运行时需要new一个不在此包中的类的对象时,才会根据全路径类名加载类;而静态导入则是随着类的加载而加载静态导入的类,所以它是提前导入的。

public class StaticTest {
	static void method1() {
		System.out.println("static method1");
	}
	
	static void method2() {
		System.out.println("static method2");
	}
}

静态导入:

import static com.starry.staticImport.StaticTest.method1;

public class Client {
	public static void main(String[] args) {
		method1();   // 
		StaticTest.method2();
	}
}

注意method1()是静态导入,所以可以不需要通过类名访问;而method2()没有导入,则需要通过类名调用。那么什么时候需要静态导入呢?

静态导入常用于静态方法以及含有静态方法的类,枚举类等的导入,可以在编译阶段确定导入类的信息或者方法信息。

static关键字的缺点

封装是Java类的三大特性之一,也是面向对象的主要特性。因为不需要通过对象,而直接通过类就能访问类的属性和方法,这有点破坏类的封装性;所以除了Utils类,代码中应该尽量少用static关键字修饰变量和方法

以上是static關鍵字有什麼作用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。