Java中的靜態(tài)內(nèi)部類(lèi)詳解及代碼示例
1. 什么是靜態(tài)內(nèi)部類(lèi)
在Java中有靜態(tài)代碼塊、靜態(tài)變量、靜態(tài)方法,當(dāng)然也有靜態(tài)類(lèi),但Java中的靜態(tài)類(lèi)只能是Java的內(nèi)部類(lèi),也稱(chēng)為靜態(tài)嵌套類(lèi)。靜態(tài)內(nèi)部類(lèi)的定義如下:
public class OuterClass { static class StaticInnerClass { ... } }
在介紹靜態(tài)內(nèi)部類(lèi)之前,首先要弄清楚靜態(tài)內(nèi)部類(lèi)與Java其它內(nèi)部類(lèi)的區(qū)別。
2. 內(nèi)部類(lèi)
什么是內(nèi)部類(lèi)?將一個(gè)類(lèi)的定義放在另一個(gè)類(lèi)的內(nèi)部,就是內(nèi)部類(lèi)。Java的內(nèi)部類(lèi)主要分為成員內(nèi)部類(lèi)、局部?jī)?nèi)部類(lèi)、匿名內(nèi)部類(lèi)、靜態(tài)內(nèi)部類(lèi)。
2.1 成員內(nèi)部類(lèi)
成員內(nèi)部類(lèi)是最普通的內(nèi)部類(lèi),就是一個(gè)普通的類(lèi)定義在另一個(gè)類(lèi)的內(nèi)部,形式如下:
public class OuterClass { class InnerClass { ... } }
注:
在成員內(nèi)部類(lèi)中,可以直接訪問(wèn)外部類(lèi)的屬性、方法,即使是private類(lèi)型也可以訪問(wèn),這是因?yàn)閮?nèi)部類(lèi)持有一個(gè)外部類(lèi)的引用,可以自由訪問(wèn)。
成員內(nèi)部類(lèi)中不能存在任何靜態(tài)變量和靜態(tài)方法。
成員內(nèi)部類(lèi)是依附于外部類(lèi)的,只有先創(chuàng)建了外部類(lèi)才能夠創(chuàng)建內(nèi)部類(lèi)。
成員內(nèi)部類(lèi)的創(chuàng)建形式如下:
//定義成員內(nèi)部類(lèi)的方式一 OuterClass test = new OuterClass(); InnerClass innerA = test.new InnerClass(); //定義成員內(nèi)部類(lèi)的方式二 OuterClass.InnerClass innerB = new OuterClass().new InnerClass();
2.2 局部?jī)?nèi)部類(lèi)
局部?jī)?nèi)部類(lèi)是定義在一個(gè)方法或者一個(gè)作用域里面的類(lèi),形式如下:
public void methodInnerClass() { class InnerClass { ... } InnerClass A = new InnerClass(); }
注:
局部?jī)?nèi)部類(lèi)就像是方法里面的一個(gè)局部變量一樣,不能有public、protected、private以及static修飾符。
可以直接訪問(wèn)外部類(lèi)的屬性、方法,即使是private類(lèi)型也可以訪問(wèn)。
2.3 匿名內(nèi)部類(lèi)
用過(guò)Swing的人應(yīng)該對(duì)匿名內(nèi)部類(lèi)非常熟悉,Swing中使用了大量的匿名內(nèi)部類(lèi)。匿名內(nèi)部類(lèi)的形式如下:
Button button = new Button(); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ... } });
注:
匿名內(nèi)部類(lèi)沒(méi)有名字,沒(méi)有構(gòu)造方法。
匿名內(nèi)部類(lèi)用于繼承其他類(lèi)或是實(shí)現(xiàn)接口,并不需要增加額外的方法,只是對(duì)繼承方法的實(shí)現(xiàn)或是重寫(xiě)。
2.4 靜態(tài)內(nèi)部類(lèi)
靜態(tài)內(nèi)部類(lèi)也是定義在另一個(gè)類(lèi)里面的類(lèi),只不過(guò)在類(lèi)的前面多了一個(gè)關(guān)鍵字static。其定義形式如下:
public class OuterClass { static class StaticInnerClass { ... } }
注:
靜態(tài)內(nèi)部類(lèi)的創(chuàng)建不依賴(lài)外部類(lèi)。
靜態(tài)內(nèi)部類(lèi)不能訪問(wèn)外部類(lèi)的非靜態(tài)成員和非靜態(tài)方法。
2.5 靜態(tài)內(nèi)部類(lèi)與其它內(nèi)部類(lèi)的區(qū)別
靜態(tài)內(nèi)部類(lèi)與其它內(nèi)部類(lèi)最大的區(qū)別在于非靜態(tài)內(nèi)部類(lèi)在編譯完成之后會(huì)隱含地保存一個(gè)引用,該引用是指向創(chuàng)建它的外部類(lèi),但是靜態(tài)內(nèi)部類(lèi)卻沒(méi)有。靜態(tài)內(nèi)部類(lèi)只是嵌套在外部類(lèi)中,因此也被稱(chēng)為嵌套內(nèi)部類(lèi)。
2.6 為什么要使用內(nèi)部類(lèi)
方便將存在一定邏輯關(guān)系的類(lèi)組織在一起,又可以對(duì)外界隱藏。
典型的情況是,內(nèi)部類(lèi)繼承自某個(gè)類(lèi)或?qū)崿F(xiàn)某個(gè)接口,內(nèi)部類(lèi)的代碼操作創(chuàng)建外部類(lèi)的對(duì)象。典型的情況是Effective Java 2.0中Item 2講述的構(gòu)建器模式。
使用內(nèi)部類(lèi)最吸引人的原因是:每個(gè)內(nèi)部類(lèi)都能獨(dú)立地繼承自一個(gè)(接口的)實(shí)現(xiàn),所以無(wú)論外圍類(lèi)是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類(lèi)都沒(méi)有影響。如果沒(méi)有內(nèi)部類(lèi)提供的可以繼承多個(gè)具體的或抽象的類(lèi)的能力,一些設(shè)計(jì)與編程問(wèn)題就很難解決。從這個(gè)角度看,內(nèi)部類(lèi)使得多重繼承的解決方案變得完整。接口解決了部分問(wèn)題,而內(nèi)部類(lèi)有效地實(shí)現(xiàn)了“多重繼承”。
3. 為什么要使用靜態(tài)內(nèi)部類(lèi)
使用靜態(tài)內(nèi)部類(lèi)主要是因?yàn)殪o態(tài)內(nèi)部類(lèi)的兩個(gè)優(yōu)點(diǎn):
增強(qiáng)了類(lèi)的封裝性
提高了代碼的可讀性
以下面的例子為例:將Builder放在NutritionFacts的內(nèi)部,說(shuō)明二者之間有一定的關(guān)系,比起將兩個(gè)類(lèi)分開(kāi)要好很多,因此增強(qiáng)了類(lèi)的封裝性。其次,二者放在一起,能很明顯的看出Builder類(lèi)是用來(lái)創(chuàng)建NutritionFacts類(lèi)的,提高了代碼的可讀性。
4. 靜態(tài)內(nèi)部類(lèi)的例子
靜態(tài)內(nèi)部類(lèi)的創(chuàng)建:
//Builder Pattern public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate; public static class Builder { // Required parameters private final int servingSize; private final int servings; // Optional parameters - initialized to default values private int calories = 0; private int fat = 0; private int carbohydrate = 0; private int sodium = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } public Builder fat(int val) { fat = val; return this; } public Builder carbohydrate(int val) { carbohydrate = val; return this; } public Builder sodium(int val) { sodium = val; return this; } public NutritionFacts build() { return new NutritionFacts(this); } } private NutritionFacts(Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } }
靜態(tài)內(nèi)部類(lèi)的使用:
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
總結(jié)
以上就是本文關(guān)于Java中的靜態(tài)內(nèi)部類(lèi)詳解及代碼示例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:Java編程子類(lèi)能否重寫(xiě)父類(lèi)的靜態(tài)方法探索、Java單例模式實(shí)現(xiàn)靜態(tài)內(nèi)部類(lèi)方法示例等,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
- java算法之靜態(tài)內(nèi)部類(lèi)實(shí)現(xiàn)雪花算法
- 淺談Java內(nèi)部類(lèi)——靜態(tài)內(nèi)部類(lèi)
- Java內(nèi)部類(lèi)應(yīng)用之靜態(tài)內(nèi)部類(lèi)應(yīng)用示例
- Java單例模式實(shí)現(xiàn)靜態(tài)內(nèi)部類(lèi)方法示例
- java 內(nèi)部類(lèi)(匿名類(lèi),匿名對(duì)象,靜態(tài)內(nèi)部類(lèi))詳解及實(shí)例
- Java編程中靜態(tài)內(nèi)部類(lèi)與同步類(lèi)的寫(xiě)法示例
- 淺談Java內(nèi)部類(lèi)與靜態(tài)內(nèi)部類(lèi)的區(qū)別
相關(guān)文章
SpringBoot+React實(shí)現(xiàn)計(jì)算個(gè)人所得稅
本文將以個(gè)人所得稅的計(jì)算為例,使用React+SpringBoot+GcExcel來(lái)實(shí)現(xiàn)這一功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下2023-09-09spring中REST和RESTful的區(qū)別以及基本實(shí)現(xiàn)
本文主要介紹了spring中REST和RESTful的區(qū)別以及基本實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04Spring Boot Admin監(jiān)控服務(wù)如何使用
這篇文章主要介紹了Spring Boot Admin監(jiān)控服務(wù)如何使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Java的反射機(jī)制---動(dòng)態(tài)調(diào)用對(duì)象的簡(jiǎn)單方法
下面小編就為大家?guī)?lái)一篇Java的反射機(jī)制---動(dòng)態(tài)調(diào)用對(duì)象的簡(jiǎn)單方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07Mybatis?Plus使用XML編寫(xiě)動(dòng)態(tài)sql的超簡(jiǎn)易方法
這篇文章主要介紹了Mybatis?Plus使用XML編寫(xiě)動(dòng)態(tài)sql的超簡(jiǎn)易方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01SpringMvc向request域中設(shè)置數(shù)據(jù)的方法
這篇文章主要介紹了SpringMvc向request域中設(shè)置數(shù)據(jù)的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09Java如何利用Mybatis進(jìn)行數(shù)據(jù)權(quán)限控制詳解
這篇文章主要介紹了Java如何利用Mybatis進(jìn)行數(shù)據(jù)權(quán)限控制詳解,數(shù)據(jù)權(quán)限控制最終的效果是會(huì)要求在同一個(gè)數(shù)據(jù)請(qǐng)求方法中,根據(jù)不同的權(quán)限返回不同的數(shù)據(jù)集,而且無(wú)需并且不能由研發(fā)編碼控制。,需要的朋友可以參考下2019-06-06