Java中的靜態(tài)內(nèi)部類詳解及代碼示例
1. 什么是靜態(tài)內(nèi)部類
在Java中有靜態(tài)代碼塊、靜態(tài)變量、靜態(tài)方法,當(dāng)然也有靜態(tài)類,但Java中的靜態(tài)類只能是Java的內(nèi)部類,也稱為靜態(tài)嵌套類。靜態(tài)內(nèi)部類的定義如下:
public class OuterClass {
static class StaticInnerClass {
...
}
}
在介紹靜態(tài)內(nèi)部類之前,首先要弄清楚靜態(tài)內(nèi)部類與Java其它內(nèi)部類的區(qū)別。
2. 內(nèi)部類
什么是內(nèi)部類?將一個(gè)類的定義放在另一個(gè)類的內(nèi)部,就是內(nèi)部類。Java的內(nèi)部類主要分為成員內(nèi)部類、局部?jī)?nèi)部類、匿名內(nèi)部類、靜態(tài)內(nèi)部類。
2.1 成員內(nèi)部類
成員內(nèi)部類是最普通的內(nèi)部類,就是一個(gè)普通的類定義在另一個(gè)類的內(nèi)部,形式如下:
public class OuterClass {
class InnerClass {
...
}
}
注:
在成員內(nèi)部類中,可以直接訪問(wèn)外部類的屬性、方法,即使是private類型也可以訪問(wèn),這是因?yàn)閮?nèi)部類持有一個(gè)外部類的引用,可以自由訪問(wèn)。
成員內(nèi)部類中不能存在任何靜態(tài)變量和靜態(tài)方法。
成員內(nèi)部類是依附于外部類的,只有先創(chuàng)建了外部類才能夠創(chuàng)建內(nèi)部類。
成員內(nèi)部類的創(chuàng)建形式如下:
//定義成員內(nèi)部類的方式一 OuterClass test = new OuterClass(); InnerClass innerA = test.new InnerClass(); //定義成員內(nèi)部類的方式二 OuterClass.InnerClass innerB = new OuterClass().new InnerClass();
2.2 局部?jī)?nèi)部類
局部?jī)?nèi)部類是定義在一個(gè)方法或者一個(gè)作用域里面的類,形式如下:
public void methodInnerClass() {
class InnerClass {
...
}
InnerClass A = new InnerClass();
}
注:
局部?jī)?nèi)部類就像是方法里面的一個(gè)局部變量一樣,不能有public、protected、private以及static修飾符。
可以直接訪問(wèn)外部類的屬性、方法,即使是private類型也可以訪問(wèn)。
2.3 匿名內(nèi)部類
用過(guò)Swing的人應(yīng)該對(duì)匿名內(nèi)部類非常熟悉,Swing中使用了大量的匿名內(nèi)部類。匿名內(nèi)部類的形式如下:
Button button = new Button();
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
...
}
});
注:
匿名內(nèi)部類沒(méi)有名字,沒(méi)有構(gòu)造方法。
匿名內(nèi)部類用于繼承其他類或是實(shí)現(xiàn)接口,并不需要增加額外的方法,只是對(duì)繼承方法的實(shí)現(xiàn)或是重寫。
2.4 靜態(tài)內(nèi)部類
靜態(tài)內(nèi)部類也是定義在另一個(gè)類里面的類,只不過(guò)在類的前面多了一個(gè)關(guān)鍵字static。其定義形式如下:
public class OuterClass {
static class StaticInnerClass {
...
}
}
注:
靜態(tài)內(nèi)部類的創(chuàng)建不依賴外部類。
靜態(tài)內(nèi)部類不能訪問(wèn)外部類的非靜態(tài)成員和非靜態(tài)方法。
2.5 靜態(tài)內(nèi)部類與其它內(nèi)部類的區(qū)別
靜態(tài)內(nèi)部類與其它內(nèi)部類最大的區(qū)別在于非靜態(tài)內(nèi)部類在編譯完成之后會(huì)隱含地保存一個(gè)引用,該引用是指向創(chuàng)建它的外部類,但是靜態(tài)內(nèi)部類卻沒(méi)有。靜態(tài)內(nèi)部類只是嵌套在外部類中,因此也被稱為嵌套內(nèi)部類。
2.6 為什么要使用內(nèi)部類
方便將存在一定邏輯關(guān)系的類組織在一起,又可以對(duì)外界隱藏。
典型的情況是,內(nèi)部類繼承自某個(gè)類或?qū)崿F(xiàn)某個(gè)接口,內(nèi)部類的代碼操作創(chuàng)建外部類的對(duì)象。典型的情況是Effective Java 2.0中Item 2講述的構(gòu)建器模式。
使用內(nèi)部類最吸引人的原因是:每個(gè)內(nèi)部類都能獨(dú)立地繼承自一個(gè)(接口的)實(shí)現(xiàn),所以無(wú)論外圍類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類都沒(méi)有影響。如果沒(méi)有內(nèi)部類提供的可以繼承多個(gè)具體的或抽象的類的能力,一些設(shè)計(jì)與編程問(wèn)題就很難解決。從這個(gè)角度看,內(nèi)部類使得多重繼承的解決方案變得完整。接口解決了部分問(wèn)題,而內(nèi)部類有效地實(shí)現(xiàn)了“多重繼承”。
3. 為什么要使用靜態(tài)內(nèi)部類
使用靜態(tài)內(nèi)部類主要是因?yàn)殪o態(tài)內(nèi)部類的兩個(gè)優(yōu)點(diǎn):
增強(qiáng)了類的封裝性
提高了代碼的可讀性
以下面的例子為例:將Builder放在NutritionFacts的內(nèi)部,說(shuō)明二者之間有一定的關(guān)系,比起將兩個(gè)類分開(kāi)要好很多,因此增強(qiáng)了類的封裝性。其次,二者放在一起,能很明顯的看出Builder類是用來(lái)創(chuàng)建NutritionFacts類的,提高了代碼的可讀性。
4. 靜態(tài)內(nèi)部類的例子
靜態(tài)內(nè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)部類的使用:
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).calories(100).sodium(35).carbohydrate(27).build();
總結(jié)
以上就是本文關(guān)于Java中的靜態(tài)內(nèi)部類詳解及代碼示例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:Java編程子類能否重寫父類的靜態(tài)方法探索、Java單例模式實(shí)現(xiàn)靜態(tài)內(nèi)部類方法示例等,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
使用JPA+querydsl如何實(shí)現(xiàn)多條件動(dòng)態(tài)查詢
這篇文章主要介紹了使用JPA+querydsl如何實(shí)現(xiàn)多條件動(dòng)態(tài)查詢,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
SpringBoot + FFmpeg實(shí)現(xiàn)一個(gè)簡(jiǎn)單的M3U8切片轉(zhuǎn)碼系統(tǒng)
使用大名鼎鼎的ffmpeg,把視頻文件切片成m3u8,并且通過(guò)springboot,可以實(shí)現(xiàn)在線的點(diǎn)播。2021-05-05
SpringBoot中處理跨域請(qǐng)求CORS的全面指南
跨域資源共享是一種安全機(jī)制,它允許Web應(yīng)用程序在一個(gè)域上的資源請(qǐng)求另一個(gè)域上的資源,下面就跟隨小編一起來(lái)深入了解下SpringBoot中處理跨域請(qǐng)求CORS的具體操作吧2025-04-04
IntelliJ IDEA 好用插件之a(chǎn)nalyze inspect code詳解
這篇文章主要介紹了IntelliJ IDEA 好用插件之a(chǎn)nalyze inspect code的相關(guān)知識(shí),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-12-12

