Java Grammar(三):修飾符
- 2020 年 3 月 17 日
- 筆記
簡介
修飾符是用於限定類型以及類型成員申明的一種符號,從修飾對象上可以分為類修飾符,方法修飾符,變量修飾符;從功能上可以劃分為訪問控制修飾符和非訪問修飾符。訪問修飾符控制訪問權限,不同的訪問修飾符有不同的權限範圍,而非訪問修飾符則是提供一些特有功能。
下面我們從功能的角度分別講解修飾符
訪問修飾符
訪問修飾符有四種:public
,private
,protected
,default
。這裡需要注意,我們這裡的default
和非訪問修飾符中的default
可不是一個東西!
這裡的default
指的是默認,什麼也不寫,在同一包內可見,不使用任何修飾符。使用對象:類、接口、變量、方法。
private
指的是在僅僅在類內可見,所以也就很好理解,private
只能修飾方法,變量,而不能修飾類和接口(畢竟你只能類內訪問,你修飾類誰能看得到呢?),修飾方法的時候,一般用於我們在重構代碼的時候提取公用代碼為內部實現方法,修飾變量的情景相比我們就經常見到了,由於Java的封裝特性,我們在定義一個類的時候,經常會把該類的屬性定義為private
,通過get
orset
方法來訪問這些變量。
而public
在我們日常中使用的比較多,我們經常會把類聲明為public
,聲明成public
的類,接口,變量,方法可以被任何類訪問,這裡需要注意一個java文件中只能包含一個public
的類,而且main
方法必須用public
修飾,否則無法被Java的解釋器識別。
protected
我們在日常的開發中使用不多,只能聲明在變量,方法,內部類上,它主要的作用就是用來保護子類的。它的含義在於子類可以用它修飾的成員,其他的不可以,它相當於傳遞給子類的一種繼承的東西。
- 基類的
protected
成員是包內可見的,並且對子類可見; - 若子類與基類不在同一包中,那麼在子類中,子類實例可以訪問其從基類繼承而來的
protected
方法,而不能訪問基類實例的protected
方法。
⬆ 大概就是上圖醬紫,湊合著看,畫圖功力賊差:)
非訪問修飾符
default
這裡的default
是jdk 8中的新特性,指的是接口方法的默認實現,在JDK 8 之前接口的方法是不能有實現的,而JDK 8 後default
修飾的方法可以在接口中進行默認的實現:
public interface Test { default void hello(){ System.out.println("Hello"); } }
就像醬紫~
static
static是面試的一個熱點,static的意思是靜態,可用於修飾變量和方法,切記一點,static是屬於類的,而非是屬於對象的,static關鍵字修飾的方法或者變量不需要依賴於對象來進行訪問,只要類被加載了,就可以通過類名去進行訪問。
而static關鍵字的基本作用就是:方便在沒有創建對象的情況下來進行調用(方法/變量)。
這裡需要注意,由於static修飾的方法和變量是屬於類的,不需要依靠對象才能使用,所以他不能訪問非static修飾的方法和變量,因為這些變量和方法是必須依託於對象才能訪問!但是非static的方法可以訪問static的方法或變量,因為當你創建對象的時候,類必定已經加載,所以可以訪問的到。
這裡需要注意一點:static不可修飾局部變量
final
final
關鍵字我們在日常中也會經常用到,通常用的最多的場景就是搭配static
一起來使用去定義我們系統的常量:
public static final String AUTHOR = "viyoung"
除了修飾變量,還可以用於修飾類和方法,被final修飾的類無法被繼承,被final修飾的方法可以被繼承,但是無法進行修改。
abstract
abstract
可以作用在類和方法上,當作用在類上時,說明這個類是一個抽象類,需要去繼承擴展,無法直接實例化一個對象,當作用在方法上的時候,說明這個方法需要擴展,被abstract
修飾的方法以分號結尾,沒有實現,而且無法被final
和static
修飾(一個需要被繼承且沒有實現的方法為毛要用這倆修飾,不是自己打自己臉嗎?):
abstract void test();
抽象類和抽象方法有以下關係:包括抽象方法的一定是抽象類,不包括抽象方法的卻不一定是非抽象類。?
synchronized
synchronized
對於了解過並發編程的同學來說比較熟悉,它可以作用於普通方法,static方法和代碼塊上,用於加鎖,放置多個線程同時訪問一個方法/類。這裡只是簡單的介紹,會在後面的並發編程中詳細講解。
volatile
volatile
修飾的成員變量具有可見性,可見性,是指線程之間的可見性,一個線程修改的狀態對另一個線程是可見的。也就是一個線程修改的結果。另一個線程馬上就能看到。比如:用volatile修飾的變量,就會具有可見性。volatile修飾的變量不允許線程內部緩存和重排序,即直接修改內存。
這裡也只是簡單的介紹,會在後面的並發編程中詳細講解。
transient
用transient關鍵字標記的成員變量不參與序列化過程,Java的serialization提供了一種持久化對象實例的機制。當持久化對象時,可能有一個特殊的對象數據成員,我們不想用serialization機制來保存它。為了在一個特定對象的一個域上關閉serialization,可以在這個域前加上關鍵字transient。當一個對象被序列化的時候,transient型變量的值不包括在序列化的表示中,然而非transient型的變量是被包括進去的。
private transient String name = "viyoung";