Java 修饰符详解:吐血整理,带你从底层语法和开发案例疏通这 11 种常见修饰符
文章目錄
- 前言
- 一、11 種常見的 Java 修飾符
- 1.1、修飾符應(yīng)用表
- 1.2、修飾符訪問權(quán)限對比
- 二、public 修飾符
- 2.1、public 修飾符語法說明
- 2.2、public 修飾符開發(fā)應(yīng)用
- 三、private 修飾符
- 3.1、private 修飾符語法說明
- 3.2、private 修飾符開發(fā)應(yīng)用
- 四、protected 修飾符
- 4.1、protected 修飾符語法說明
- 4.2、protected 修飾符開發(fā)應(yīng)用
- 五、default 修飾符(不加任何訪問權(quán)限修飾符)
- 5.1、default 修飾符語法說明
- 5.2、default 修飾符開發(fā)應(yīng)用
- 六、static 修飾符
- 6.1、類(靜態(tài))變量與實例變量
- 6.1.1、類(靜態(tài))變量與實例變量語法說明
- 6.1.2、類(靜態(tài))變量與實例變量開發(fā)應(yīng)用
- 6.2、類(靜態(tài))方法與實例方法
- 6.2.1、類(靜態(tài))方法與實例方法語法說明
- 6.2.2、類(靜態(tài))方法與實例方法開發(fā)應(yīng)用
- 6.3、static 靜態(tài)代碼段
- 6.3.1、static 靜態(tài)代碼段語法說明
- 6.3.2、static 靜態(tài)代碼段開發(fā)應(yīng)用
- 6.4、static 內(nèi)部類
- 七、final 修飾符
- 7.1、final 修飾符語法說明
- 7.2、final 修飾符開發(fā)應(yīng)用
- 八、abstract 修飾符
- 8.1、abstract 修飾符語法說明
- 8.2、abstract 修飾符開發(fā)應(yīng)用
- 九、接口(特殊的抽象類)
- 9.1、接口語法說明
- 9.2、接口開發(fā)應(yīng)用
- 9.3、抽象類和接口的區(qū)別是什么?
- 9.4、什么是適配器?
- 總結(jié)
前言
在 Java 的語言體系中共有 11 種常見的修飾符,其在我們?nèi)粘5拈_發(fā)中一般有四種使用情況:成員變量、成員方法、代碼塊和內(nèi)部類,那么在應(yīng)用過程中我們還應(yīng)該具體注意些什么?通過本文中我們將從最基礎(chǔ)的底層和原理來理解和疏通這些常見修飾符語法說明以及在常見的開發(fā)中如何使用。一、11 種常見的 Java 修飾符
1.1、修飾符應(yīng)用表
| (default) | √ | √ | √ | √ | √ | 類、構(gòu)造方法、方法或數(shù)據(jù)域在所在的包中可見 |
| public | √ | √ | √ | √ | 類、構(gòu)造方法、方法或數(shù)據(jù)域在任何包任何程序中都可見 | |
| private | √ | √ | √ | 構(gòu)造方法、方法或數(shù)據(jù)域只在所在的類中可見 | ||
| protected | √ | √ | √ | 構(gòu)造方法、方法或數(shù)據(jù)域在所屬的包中可見,或者在任何包中該類的子類中可見 | ||
| static | √ | √ | √ | 定義類方法、類數(shù)據(jù)域或靜態(tài)初始化模塊 | ||
| final | √ | √ | √ | 終極類不能擴展。終極方法不能在子類中修改。終極數(shù)據(jù)域是常量 | ||
| abstract | √ | √ | 抽象類必須被擴展。抽象方法必須在具體的子類中實現(xiàn) | |||
| native | √ | 用native修飾的方法表明它是用Java以外的語言實現(xiàn)的 | ||||
| synchronized | √ | √ | 同一時間只有一個線程可以執(zhí)行這個方法 | |||
| strictfp | √ | √ | 使用精確浮點數(shù)計算模式,保證在所有的Java虛擬機中計算結(jié)果都相同 | |||
| transient | √ | 標(biāo)記實例數(shù)據(jù)域,使其不進行序列化 |
1.2、修飾符訪問權(quán)限對比
public > protected > default > private
說明:以下僅介紹我們常用的 7 種修飾符語法說明以及開發(fā)應(yīng)用說明,另外 4 種用法查看修飾符應(yīng)用表即可。
二、public 修飾符
2.1、public 修飾符語法說明
- 修飾類、方法、變量。
- 可以在任意位置訪問,公共的。
2.2、public 修飾符開發(fā)應(yīng)用
- 開發(fā)中,通常類和業(yè)務(wù)方法都使用 public 修飾。
三、private 修飾符
3.1、private 修飾符語法說明
- 修飾方法、變量、還可以修飾內(nèi)部類。
- 只能在本類中訪問,私有的。
3.2、private 修飾符開發(fā)應(yīng)用
- 開發(fā)中,通常實體類(Entity,Vo)中的成員變量使用 private 修飾,會提供訪問這些變量的方法 getter 或 setter,原則上要求不準(zhǔn)定義私有的方法。
- 一個實體數(shù)據(jù)的表通常對應(yīng)一個實體類。
四、protected 修飾符
4.1、protected 修飾符語法說明
- 修飾方法、變量、還可以修飾內(nèi)部類。
- 同一個包可以訪問、子類可以訪問(子類和父類不在同一個包也可以訪問)。
4.2、protected 修飾符開發(fā)應(yīng)用
- 開發(fā)中,通常方法或變量是用來繼承的,都使用 protected 修飾。
- 在繼承中,方法的重寫,子類方法的訪問權(quán)限必須大于或等于父類方法的訪問權(quán)限,舉例代碼如下:
五、default 修飾符(不加任何訪問權(quán)限修飾符)
說明:使用 default 修飾符與不加任何訪問權(quán)限修飾符效果是一樣的。
5.1、default 修飾符語法說明
- 修飾類、方法、變量。
- 只能在同一個包中訪問,子類也必須在同一個包中。
5.2、default 修飾符開發(fā)應(yīng)用
- 項目中,類、方法、變量根據(jù)需求,通常都會指定訪問權(quán)限。
六、static 修飾符
由于static 修飾符作用較多,我們對其拆開進行逐步分析。
6.1、類(靜態(tài))變量與實例變量
- 類變量:被存儲在方法區(qū)中,“只有一份”,被所有對象共享。當(dāng)類被加載的時候,立即被存儲在方法區(qū)中,當(dāng)類被卸載,類變量立即釋放內(nèi)存。
- 實例變量:在創(chuàng)建對象之后,被分配到堆內(nèi)存中,實例變量屬于某個具體的對象。當(dāng)創(chuàng)建對象,實例變量出現(xiàn)在堆內(nèi)存中,當(dāng)對象被垃圾回收,實例變量立即釋放內(nèi)存。
比如我們創(chuàng)建兩個對象,代碼如下:
Cell c1 = new Cell(4,5); Cell c2 = new Cell(5,6);當(dāng)創(chuàng)建對象 c1,c2 時,實例變量(4,5),(5,6)出現(xiàn)在堆內(nèi)存中,當(dāng)對象 c1,c2 被垃圾回收,實例變量立即釋放內(nèi)存。
6.1.1、類(靜態(tài))變量與實例變量語法說明
- Java 中 可以通過 static 關(guān)鍵字修飾變量達到全局變量的效果。
- static 修飾的變量(靜態(tài)變量)屬于類,在類第一次通過類加載器到 jvm 時被分配至方法區(qū),所以我們也稱其為類變量。
- 沒有 static 修飾的變量,稱為實例變量。
6.1.2、類(靜態(tài))變量與實例變量開發(fā)應(yīng)用
- 類變量可以由類名直接訪問,開發(fā)中推薦使用類名的全稱。
比如我們定義一個實體類,代碼如下:
public class Student {// 實例變量,在創(chuàng)建對象之后,被分配到堆內(nèi)存中,實例變量屬于某個具體的對象// 當(dāng)創(chuàng)建對象,實例變量出現(xiàn)在堆內(nèi)存中,當(dāng)對象被垃圾回收,實例變量立即釋放內(nèi)存String name;// 類變量,被存儲在方法區(qū)中,"只有一份",被所有對象共享static String jtName;public void print() {System.out.println(this.name);System.out.println(jtName);} }下次使用靜態(tài)變量 jtName 時,我們直接使用 Student 這個類名直接調(diào)用即可。
同時我們也就可以理解下面兩個對象的屬性取值是一樣的,代碼如下:
6.2、類(靜態(tài))方法與實例方法
- 靜態(tài)方法:static 修飾的方法屬于類方法,不需要創(chuàng)建對象就可以調(diào)用。static 方法中不能使用 this 和 super 等關(guān)鍵字,不能調(diào)用非 static 方法,只能訪問所屬類的靜態(tài)成員變量和靜態(tài)方法。靜態(tài)方法(類方法),當(dāng)類被加載,靜態(tài)方法立即被加載到方法區(qū)中,類方法可以由類名直接調(diào)用。
- 實例方法:沒有 static 修飾的方法,實例方法,當(dāng)創(chuàng)建對象之后,實例方法立即被加載到方法區(qū)中,多個實例共享一份實例方法。
6.2.1、類(靜態(tài))方法與實例方法語法說明
- 類方法中,不能使用 this 關(guān)鍵字,類方法中不隱含調(diào)用該方法對象的參數(shù)。
- 實例方法可以直接調(diào)用靜態(tài)方法,靜態(tài)方法不可以直接訪問實例成員,必須創(chuàng)建對象,由對象訪問。
- 所有對象共享的數(shù)據(jù),定義為靜態(tài)變量,否則定義為實例變量方法,方法中沒有訪問實例成員,可以定義為靜態(tài)方法。
6.2.2、類(靜態(tài))方法與實例方法開發(fā)應(yīng)用
- 項目中,通常工具類中的方法,都是靜態(tài)的。
6.3、static 靜態(tài)代碼段
6.3.1、static 靜態(tài)代碼段語法說明
- JVM 在加載類時會執(zhí)行 static 靜態(tài)代碼段,常用于初始化靜態(tài)變量。
- static 代碼只會在類被加載時執(zhí)行且執(zhí)行一次。
- 靜態(tài)優(yōu)于對象。
6.3.2、static 靜態(tài)代碼段開發(fā)應(yīng)用
- 開發(fā)中,通常用于加載靜態(tài)資源,讀取配置文件等操作,在靜態(tài)代碼段中實現(xiàn)。
比如我們定義一個工具類,代碼如下:
public class SomeUtil {// 默認的無參構(gòu)造public SomeUtil() {System.out.println("創(chuàng)建對象!");}// 靜態(tài)優(yōu)于對象// 靜態(tài)代碼段 當(dāng)類被加載,立即被執(zhí)行,一個類在同一個進程中,只加載一次static {System.out.println("加載靜態(tài)資源!");}// 實例代碼段{System.out.println("實例代碼段!");}public static void do1() {System.out.println("do1....");}public static void do2() {System.out.println("do2....");}public static void do3() {System.out.println("do3....");}public static void main(String[] args) {SomeUtil.do1();SomeUtil.do2();SomeUtil.do3();SomeUtil s1 = new SomeUtil();SomeUtil s2 = new SomeUtil();} }執(zhí)行 main 方法,根據(jù)輸出的內(nèi)容我們可以明確看出執(zhí)行的順序。靜態(tài)代碼段只執(zhí)行一次,然后是靜態(tài)方法被執(zhí)行,最后是 new 的對象執(zhí)行無參構(gòu)造和實例代碼段,new 一次執(zhí)行一次。
同時也可以得出我們的結(jié)論:靜態(tài)優(yōu)于對象,如下圖所示:
6.4、static 內(nèi)部類
- static 內(nèi)部類可以不依賴外部類實例對象而被實例化,而內(nèi)部類需要在外部類實例化后才能被實例化。
- 靜態(tài)內(nèi)部類不能訪問外部類的普通變量,只能訪問外部類的靜態(tài)成員變量和靜態(tài)方法。
七、final 修飾符
7.1、final 修飾符語法說明
- final 類,不能被繼承。
- final 方法,不能被重寫。
- final 修飾的變量,是常量。
7.2、final 修飾符開發(fā)應(yīng)用
- 開發(fā)中,我們使用 final 定義數(shù)據(jù)字典。
比如:在如下 Card 類中我們定義數(shù)據(jù)字典,用于 main 函數(shù)的輸出和查詢。
說明:數(shù)據(jù)字典是指對數(shù)據(jù)的數(shù)據(jù)項、數(shù)據(jù)結(jié)構(gòu)、數(shù)據(jù)流、數(shù)據(jù)存儲、處理邏輯等進行定義和描述,其目的是對數(shù)據(jù)流程圖中的各個元素做出詳細的說明,使用數(shù)據(jù)字典為簡單的建模項目。簡而言之,數(shù)據(jù)字典是描述數(shù)據(jù)的信息集合,是對系統(tǒng)中使用的所有數(shù)據(jù)元素的定義的集合。
舉例使用 final 定義數(shù)據(jù)字典,代碼如下:
public class Card {// 開發(fā)中,使用final定義數(shù)據(jù)字典。public static final int SPADE = 1;public static final int HEART = 2;public static final int BLACK = 5;public static final int FLOWER = 6;public static final int THREE = 0;public static final int EIGHT = 5;public static final int JACK = 8;public static final int QUEEN = 9;public static final int KING = 10;public static final int ACE = 11;public static final int DUCE = 12;public static final int JOKER = 13;private int suit;private int num;public Card() {}public Card(int suit, int num) {this.suit = suit;this.num = num;}public int getSuit() {return suit;}public void setSuit(int suit) {this.suit = suit;}public int getNum() {return num;}public void setNum(int num) {this.num = num;}public static void main(String[] args) {Card card = new Card(Card.HEART, Card.THREE);System.out.println(card.getNum());} }八、abstract 修飾符
8.1、abstract 修飾符語法說明
- 抽象的,可以修飾類,修飾方法。
修飾抽象類:
- 抽象類存在的意義在于被繼承。
- 抽象類不可以創(chuàng)建對象。
- abstract 不能和 final 一起使用 。
修飾抽象方法:
- 抽象方法,只有定義沒有實現(xiàn)。
- 如果一個類中有抽象方法,這個類必須是抽象類。
- 一個抽象類中,可以沒有抽象方法。
- 抽象類的子類,必須實現(xiàn)父類中所有的抽象方法。
8.2、abstract 修飾符開發(fā)應(yīng)用
- 抽象類中既可以有默認實現(xiàn)的方法,又可以有沒有實現(xiàn)的方法。
- 接口的適配器——用子類去實現(xiàn)接口中的方法。
九、接口(特殊的抽象類)
9.1、接口語法說明
- 特殊的抽象類接口中的方法都是抽象方法,接口中的變量都是靜態(tài)常量。
- 定義接口使用 interface 關(guān)鍵字。
- 實現(xiàn)接口使用 implements 關(guān)鍵字。
- 類實現(xiàn)了接口,必須實現(xiàn)接口中所有的方法。
如下我們定義了一個接口 MyInterface,代碼如下:
public interface MyInterface {// 接口是高一級別的抽象。不能被實例化,所以只能定義常量// 定義了變量需要實例化,賦值才能使用,跟接口違背// 特殊的抽象類 接口中的方法都是抽象方法 接口中的變量都是靜態(tài)常量int I = 10;// 如果類中所有的方法都是抽象方法,使用接口void method1();void method2(); }這里我們 MyImpClass 類實現(xiàn)了接口,就必須實現(xiàn)接口中所有的方法,代碼如下:
import java.io.Serializable;/*** 其實適配器只是一個類,它實現(xiàn)了某種接口,提供了方法體。 * 這樣,再用到這個接口時,可以直接繼承適配器,這樣就不需要把接口中的每一個方法再填充一遍了。* 只需要在這個類中復(fù)寫一下需要用的方法。這樣簡單,方便。* * @author bailu* */ public class MyImpClass implements MyInterface, Serializable {// Serializable序列化private static final long serialVersionUID = 1L;// 重寫接口的方法——適配器,@Overridepublic void method1() {System.out.println(I);}@Overridepublic void method2() {} }9.2、接口開發(fā)應(yīng)用
- 如果類中所有的方法都是抽象方法,使用接口。
- 接口是用來制定標(biāo)準(zhǔn)或規(guī)范。
- 可以降低組件之間的耦合度,擴展組件的功能。
- 體現(xiàn)了設(shè)計模式中的開閉原則。
9.3、抽象類和接口的區(qū)別是什么?
- 抽象類中,可以定義抽象方法和非抽象方法。接口中,所有的方法都是抽象方法。
- 一個類只能繼承一個抽象類。一個類可以實現(xiàn)多個接口,多個接口使用逗號分隔。
如下的類既實現(xiàn)了接口 MyInterface,同時實現(xiàn)了 Serializable 序列化序列化,代碼如下:
import java.io.Serializable;/**- 其實適配器只是一個類,它實現(xiàn)了某種接口,提供了方法體。 - 這樣,再用到這個接口時,可以直接繼承適配器,這樣就不需要把接口中的每一個方法再填充一遍了。- 只需要在這個類中復(fù)寫一下需要用的方法。這樣簡單,方便。- - @author bailu- */ public class MyImpClass implements MyInterface, Serializable {// Serializable序列化private static final long serialVersionUID = 1L;// 重寫接口的方法——適配器,@Overridepublic void method1() {System.out.println(I);}@Overridepublic void method2() {} }- 抽象類之間也可以繼承,但是也只是支持單繼承。
- 接口之間也可以繼承,一個接口可以繼承多個接口。
9.4、什么是適配器?
適配器只是一個類,它實現(xiàn)了接口,提供了方法體。再用到這個接口時,可以直接繼承適配器,這樣就不需要把接口中的每一個方法再填充一遍了,只需要在這個類中復(fù)寫一下需要用的方法。
接口很好地體現(xiàn)了設(shè)計模式中的開閉原則。
比如,我們做一個在線商城系統(tǒng),就需要調(diào)用第三方支付——銀行或者是支付寶的支付接口。我們就需要第三方為我們提供接口,里面定義了抽象的方法以及實現(xiàn)接口的方法——適配器,我們通過調(diào)用適配器里面的方法來完成支付,代碼如下:
ZsBankInter obj = 獲取實現(xiàn)類對象; obj.send(); 京東、淘寶 銀行接口ZsBankInter send() 類 class DoSend implements ZsBankInter{send()具體的方法 }總結(jié)
修飾符在 Java 語言中有四種使用情況:成員變量、成員方法、代碼塊和內(nèi)部類。以上我們總結(jié)了在日常的開發(fā)過程中會遇到的 11 種常見的修飾符,并從最基礎(chǔ)的底層和原理理解和疏通這些常見修飾符語法說明以及常見的開發(fā)應(yīng)用案例。其中具體的內(nèi)容還有很多,本文就暫不一一列舉,待日后根據(jù)開發(fā)需要補充完畢。我是白鹿,一個不懈奮斗的程序猿。望本文能對你有所裨益,歡迎大家的一鍵三連!若有其他問題、建議或者補充可以留言在文章下方,感謝大家的支持!
總結(jié)
以上是生活随笔為你收集整理的Java 修饰符详解:吐血整理,带你从底层语法和开发案例疏通这 11 种常见修饰符的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 反洗钱势在必行,洗钱行为不可取
- 下一篇: 三分利息算高利贷吗