Java基礎(chǔ)教程之static五大應(yīng)用場景
前言
static和final是兩個(gè)我們必須掌握的關(guān)鍵字。不同于其他關(guān)鍵字,他們都有多種用法,而且在一定環(huán)境下使用,可以提高程序的運(yùn)行性能,優(yōu)化程序的結(jié)構(gòu)。上一個(gè)章節(jié)我們講了final關(guān)鍵字的原理及用法,本章節(jié)我們來了解一下static關(guān)鍵字原理及其用法。
一. static特點(diǎn)
static是一個(gè)修飾符,通常用于修飾變量和方法,如開發(fā)過程中用到的字典類數(shù)據(jù)都會(huì)用到static來修飾,工具類方法,如Dateutils,Stringutils這類工具方法也會(huì)用到static來修飾,那么除了這兩種最常用的場景外,是否還有其他場景呢,答案是:有的,總共五種:
- static變量
- static方法
- static代碼塊
- static內(nèi)部類
- static包內(nèi)導(dǎo)入
static修飾的變量、方法、代碼塊、內(nèi)部類在類加載期間就已經(jīng)完成初始化,存儲(chǔ)在Java Heap(JDK7.0之前存儲(chǔ)在方法區(qū))中靜態(tài)存儲(chǔ)區(qū),因此static優(yōu)于對象而存在。
static修飾的成員(變量、方法)被所有對象所共享,也叫靜態(tài)變量或靜態(tài)方法,可直接通過類調(diào)用(也建議通過類調(diào)用)。
二. static 變量
static變量隨著類的加載而存在,隨著類的消失而消失,當(dāng)類被加載時(shí),就會(huì)為靜態(tài)變量在Java Heap中分配內(nèi)存空間,可以通過【類.變量名】和【對象.變量名】的方式調(diào)用,建議直接使用【類.變量名】的方式,
public class Person { private String name; private static int eyeNum; public static int legNum = 2; public String getName() { return name; } public void setName(String name) { this.name = name; } public static int getEyeNum() { return eyeNum; } public static void setEyeNum(int eyeNum) { Person.eyeNum = eyeNum; } }
public static void main(String[] args) { Person person = new Person(); person.setEyeNum(25); Person person1 = new Person(); person1.setEyeNum(28); System.out.println(person.getEyeNum());//28 System.out.println(person1.getEyeNum());//28 int legNum = person.legNum; System.out.println(legNum);//2 }
從上面的例子可以看出靜態(tài)變量是對所有對象共享,一個(gè)對象對其值的改動(dòng),直接就會(huì)造成另一個(gè)對象取值的不同。
什么時(shí)候使用static變量?
作為共享變量使用,通常搭配final關(guān)鍵字一起使用,比如我們常用的字典類數(shù)據(jù);
private static final String GENERAL_MAN = "man";
減少對象的創(chuàng)建,比如在類開頭的部分,定義Logger方法,用于異常日志采集
private static Logger LOGGER = LogFactory.getLoggger(MyClass.class);
始終返回同一變量,比如我們的單例模式。
三. static 方法
靜態(tài)方法只能訪問靜態(tài)成員(靜態(tài)變量、靜態(tài)方法),而非靜態(tài)方法既可訪問靜態(tài)方法也可訪問非靜態(tài)方法;因?yàn)殪o態(tài)成員優(yōu)于對象而存在,因此無法調(diào)用和對象相關(guān)的關(guān)鍵字,如this,super,無法通過關(guān)鍵字訪問對象資源。
public class Person { private String name; private static int eyeNum; public static int legNum = 2; public String getName() { return name; } public void setName(String name) { this.name = name; } public static int getEyeNum() { System.out.println(name);//編譯出錯(cuò),name不可用 return eyeNum; } public static void setEyeNum(int eyeNum) { Person.eyeNum = eyeNum; this.name = "";//編譯出錯(cuò),this不可用 } }
什么時(shí)候使用static方法?
static方法一般用于與當(dāng)前對象無法的工廠方法、工具方法。如Math.sqrt(),Arrays.sort(),StringUtils.isEmpty()等。
四. static 代碼塊
static代碼塊相對于static變量和static方法來說使用不是那么廣泛,但也算是比較常見的用法了,static代碼塊在加載一個(gè)類的時(shí)候最先執(zhí)行,且只執(zhí)行一次。
public static Map<String, String> timeTypes; static { timeTypes = new HashMap<>(); timeTypes.put("year", "年"); timeTypes.put("quarter", "季"); timeTypes.put("month", "月"); timeTypes.put("day", "日"); System.out.println("初始化1"); } public static void main(String[] args) { System.out.println("初始化2"); }
執(zhí)行結(jié)果是:
初始化1;
初始化2;
什么時(shí)候使用static代碼塊?
一般在進(jìn)行初始化操作時(shí),比如讀取配置文件信息,獲取當(dāng)前服務(wù)器參數(shù)等
五. static內(nèi)部類
定義一個(gè)內(nèi)部類,加上static,就成為了一個(gè)static內(nèi)部類,static只能修飾內(nèi)部類,不能修飾頂級(jí)類,靜態(tài)內(nèi)部類在業(yè)務(wù)應(yīng)用系統(tǒng)開發(fā)中使用的不多。
public class StaticCouter { private String str0 = "hi"; //非靜態(tài)變量 private static String str1 = "hello"; //靜態(tài)變量 static class StaticInnerClass{//靜態(tài)內(nèi)部類 public void getMessage(){ System.out.println(str0);//編譯出錯(cuò) System.out.println(str1); } } class NormalInnerClass{//非靜態(tài)內(nèi)部類 public void getMessage(){ System.out.println(str0); System.out.println(str1); } } }
靜態(tài)內(nèi)部類與非靜態(tài)內(nèi)部類有何異同?
靜態(tài)內(nèi)部類 | 非靜態(tài)內(nèi)部類 |
---|---|
不需要有指向外部類的引用 | 必須通過外部類的new關(guān)鍵字引用 |
可定義普通變量和方法,也可定義靜態(tài)變量和方法 | 可定義普通變量和方法,不可定義靜態(tài)變量和方法 |
可以調(diào)用外部類的靜態(tài)成員,不能調(diào)用外部類的普通成員 | 可調(diào)用外部類的普通成員和靜態(tài)成員 |
public static void main(String[] args) { //創(chuàng)建靜態(tài)內(nèi)部類實(shí)例 StaticInnerClass staticInnerClass = new StaticInnerClass(); //調(diào)用靜態(tài)內(nèi)部類方法 staticInnerClass.getMessage(); //創(chuàng)建靜態(tài)內(nèi)部類實(shí)例 StaticCouter.StaticInnerClass staticInnerClass1 = new staticCouter.StaticInnerClass(); //調(diào)用靜態(tài)內(nèi)部類方法 staticInnerClass1.getMessage(); //創(chuàng)建普通內(nèi)部類實(shí)例 StaticCouter.NormalInnerClass normalInnerClass = new StaticCouter().new NormalInnerClass(); //調(diào)用普通內(nèi)部類方法 normalInnerClass.getMessage(); }
六. static包內(nèi)導(dǎo)入
這個(gè)概念不太好理解,舉個(gè)例子
public static void main(String[] args) { int[] arra = {1,4,5,7}; Arrays.sort(arra); Arrays.asList(arra); Arrays.fill(arra, 6); }
static包導(dǎo)入目的就是去掉重復(fù)的Arrays類名調(diào)用
通過在頂部引入
import static java.util.Arrays.*
即可把Arrays類中所有的靜態(tài)變量,方法,內(nèi)部類等都引入當(dāng)前類中,調(diào)用時(shí)直接調(diào)用sort(arra),asList(arra),
java5后引入的,不常用,調(diào)用類方法時(shí)會(huì)比較簡單,但可讀性不好,慎用。
七. 總結(jié)
static是java中很常用的一個(gè)關(guān)鍵字,使用場景也很多,本文主要介紹了它的五種用法,static變量,static方法,static代碼塊,static內(nèi)部類,static包內(nèi)導(dǎo)入,若有不對之處,請批評指正,望共同進(jìn)步,謝謝!
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對腳本之家的支持。
相關(guān)文章
解決Springboot集成Redis集群配置公網(wǎng)IP連接報(bào)私網(wǎng)IP連接失敗問題
在Springboot 集成 Redis集群配置公網(wǎng)IP連接報(bào)私網(wǎng)IP連接失敗,一直報(bào)私有IP連接失敗,所以本文小編給大家介紹了如何解決報(bào)錯(cuò)問題,如果有遇到相同問題的同學(xué),可以參考閱讀本文2023-10-10淺析Java設(shè)計(jì)模式編程中的單例模式和簡單工廠模式
這篇文章主要介紹了淺析Java設(shè)計(jì)模式編程中的單例模式和簡單工廠模式,使用設(shè)計(jì)模式編寫代碼有利于團(tuán)隊(duì)協(xié)作時(shí)程序的維護(hù),需要的朋友可以參考下2016-01-01Java的synchronized關(guān)鍵字深入解析
這篇文章主要介紹了Java的synchronized關(guān)鍵字深入解析,在并發(fā)編程中,多線程同時(shí)并發(fā)訪問的資源叫做臨界資源,當(dāng)多個(gè)線程同時(shí)訪問對象并要求操作相同資源時(shí),分割了原子操作就有可能出現(xiàn)數(shù)據(jù)的不一致或數(shù)據(jù)不完整的情況,需要的朋友可以參考下2023-12-12springboot實(shí)現(xiàn)定時(shí)器(一看即會(huì),非常簡單)
這篇文章主要介紹了springboot實(shí)現(xiàn)定時(shí)器(一看即會(huì),非常簡單),具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12