java後端知識點快速梳理——java基礎
面向物件
java三大特性
- 封裝: 將事務封裝成一個類,達到解耦,隱藏細節的效果。通過get/set等方法,封裝了內部邏輯,並保留了特定的介面與外界聯絡。
- 繼承: 從一個已知的類中派生出一個新的類,新類可以擁有已知類的行為和屬性,並且可以通過覆蓋/重寫來增強已知類的能力。
- 多型: 同一個實現介面,使用不同的例項而執行不同的操作。繼承是多型的基礎,沒有繼承就沒有多型。
關於繼承
- Java中不支援多繼承,即一個類只可以有一個父類存在。
- Java中的建構函式是不可以繼承的,如果一個父類建構函式時私有的,那麼久不允許有子類存在。
- 子類擁有父類非private的屬性和方法
- 子類可以新增自己的方法和屬性,即對父類進行擴充套件
- 子類可以重新定義父類的方法,即方法的覆蓋/重寫
關於覆蓋/重寫(@Override)
子類中的方法與父類中繼承的方法有完全相同的返回值型別、方法名、引數個數以及引數型別,但子類豐富或修改了功能。
關於過載
過載是指在一個類中(包括父類)存在多個同名的不同方法,這些方法的引數個數,順序以及型別不同均可以構成方法的過載。如果僅僅是修飾符、返回值、丟擲的異常不同,那麼這是兩個相同的方法。
所以只有方法返回值不同是不能構成過載的
如:
public int add(int a, int b){}
public void add(int a, int b){}
在呼叫add方法的時候,系統並不知道你要呼叫哪一個。
子類與父類的相互轉型
假設有兩個類,Father是父類,Son是其子類。
- 向上轉型
子類物件轉為父類,父類可以是介面。
Father f1 = new Son();
問題:在向上轉型的過程中,我們容易出現方法丟失的問題,比如我們將一個匯出類(子類)進行向上轉型,但是在基類(父類)中可能缺少部分匯出類(子類)的方法,所以我們對匯出類(子類)進行向上轉型之後,使用基類(父類)物件去呼叫方法,只能呼叫基類(父類)有的方法。
- 向下轉型
父類物件轉為子類
Son s1 = (Son) f1;
注意:該父類必須實際指向了一個子類物件才可強制型別向下轉型,看看下面的錯誤例子
Father f2 = new Father(); Son s2 = (Son)f2;
為什麼Son s1 = (Son) f1;
可以轉型而Son s2 = (Son)f2;
轉型失敗?
因為 f1 指向一個子類物件,但 f2 被傳給了一個 Father 物件,這也就說明了該父類必須實際指向了一個子類物件才可強制型別向下轉型
JDK, JRE, JVM
- JDK: java 開發工具包,包含了JRE,同時還包含了java編譯器javac、監控工具jconsole、分析工具jvisualvm
- JRE: java 執行時環境,包含了java虛擬機器、java基礎類庫
- JVM: 是指Java虛擬機器,當我們執行一個程式時,JVM負責將位元組碼轉換為特定機器程式碼,JVM提供了記憶體管理/垃圾回收和安全機制等
區別與聯絡:
- JDK是開發工具包,用來開發Java程式,而JRE是Java的執行時環境
- JDK和JRE中都包含了JVM
- JVM是Java程式設計的核心,獨立於硬體和作業系統,具有平臺無關性,而這也是Java程式可以一次編寫,多處執行的原因
Java語言的平臺無關性是如何實現的?
- JVM遮蔽了作業系統和底層硬體的差異
- Java面向JVM程式設計,先編譯生成位元組碼檔案,然後交給JVM解釋成機器碼執行
- 通過規定基本資料型別的取值範圍和行為
抽象類與介面
java中通過abstract
來定義抽象類,通過interface
關鍵字來定義介面
抽象類和介面的主要區別可以總結如下:
- 抽象類中可以沒有抽象方法,也可以抽象方法和非抽象方法共存
- 介面中的方法在JDK8之前只能是抽象的,JDK8版本開始提供了介面中方法的default實現
- 抽象類和類一樣是單繼承的,但介面可以繼承多個介面
- 抽象類中可以存在普通的成員變數;介面中的變數必須是static final型別的,必須被初始化,介面中只有常量,沒有變數
8種基本資料型別
資料型別 | 位元組 | 位 |
---|---|---|
byte | 1 | 8 |
short | 2 | 16 |
int | 4 | 32 |
long | 8 | 64 |
float | 4 | 32 |
double | 8 | 64 |
char | 2 | 16 |
boolean | - | - |
注:boolean沒有規定
註解
註解的本質就是一個繼承了 Annotation 介面的介面,用來將任何的資訊或元資料(metadata)與程式元素(類、方法、成員變數等)進行關聯。程式可以通過反射獲取標註內容。
註解的作用
代替繁雜的配置檔案,簡化開發。
定義註解
public @interface MyAnnotation {
String value();
int value1();
}
// 使用註解MyAnnotation,可以設定屬性
@MyAnnotation(value1=100,value="hello")
public class MyClass {
}
從程式碼可以看出,定義註解使用的是@interface,可以在方法內部定義屬性。
元註解
元註解的作用就是負責註解其他註解。Java中提供了4個元註解。
- @Target:說明註解所修飾的物件範圍
原始碼如下:
public @interface Target {
ElementType[] value();
}
public enum ElementType {
TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE,TYPE_PARAMETER,TYPE_USE
}
用例
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnnotation {
}
說明: 這表明MyAnnotation只能作用域類/介面和方法上。
- @Retention:(保留策略): 保留策略定義了該註解被保留的時間長短。
原始碼如下:
public @interface Retention {
RetentionPolicy value();
}
public enum RetentionPolicy {
SOURCE, CLASS, RUNTIME
}
說明: SOURCE:表示在原始檔中有效(即原始檔保留);CLASS:表示在class檔案中有效(即class保留);RUNTIME:表示在執行時有效(即執行時保留)
- @Documented: 宣告註解能夠被javadoc等識別
- @Inherited: 宣告子類可以繼承此註解,如果一個類A使用此註解,則類A的子類也繼承此註解
反射
反射機制是指在執行中,對於任意一個類,都能夠知道這個類的所有屬性和方法。對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。即動態獲取資訊和動態呼叫物件方法的功能稱為反射機制。
(未完待續)
java異常體系
異常主要分為Exception和Error
Throwable 是 Java 語言中所有錯誤與異常的超類。Throwable 包含兩個子類:Error(錯誤)和 Exception(異常),它們通常用於指示發生了異常情況。
Exception和Error有什麼區別?
- Exception是程式正常執行中預料到可能會出現的錯誤,並且應該被捕獲並進行相應的處理,是一種異常現象.Exception又分為了執行時異常和編譯時異常。
- 編譯時異常(受檢異常): 表示當前呼叫的方法體內部丟擲了一個異常,所以編譯器檢測到這段程式碼在執行時可能會出異常,所以要求我們必須對異常進行相應的處理,可以捕獲異常或者拋給上層呼叫方。
- 執行時異常(非受檢異常): 表示在執行時出現的異常,常見的執行時異常包括:空指標異常,陣列越界異常,數字轉換異常以及算術異常等。
- Error是正常情況下不可能發生的錯誤,Error會導致JVM處於一種不可恢復的狀態
NoClassDefFoundError 和 ClassNotFoundException 區別?
- NoClassDefFoundError 是一個 Error 型別的異常,是由 JVM 引起的,不應該嘗試捕獲這個異常。引起該異常的原因是 JVM 或 ClassLoader 嘗試載入某類時在記憶體中找不到該類的定義,該動作發生在執行期間,即編譯時該類存在,但是在執行時卻找不到了,可能是變異後被刪除了等原因導致;
- ClassNotFoundException 是一個受查異常,需要顯式地使用 try-catch 對其進行捕獲和處理,或在方法簽名中用 throws 關鍵字進行宣告。當使用 Class.forName, ClassLoader.loadClass 或 ClassLoader.findSystemClass 動態載入類到記憶體的時候,通過傳入的類路徑引數沒有找到該類,就會丟擲該異常;另一種丟擲該異常的可能原因是某個類已經由一個類載入器載入至記憶體中,另一個載入器又嘗試去載入它。
捕獲異常應該遵循哪些原則
- 不要使用Exception捕獲,而是儘可能詳細的寫出要捕獲的異常;
- 使用日誌記錄,方便以後排查;
- 不要使用try-catch去包住一塊很大的程式碼塊,這不利於排查問題;
java異常處理關鍵字
throw 和 throws 的區別是什麼?
- throw 關鍵字用在方法內部,只能用於丟擲一種異常,用來丟擲方法或程式碼塊中的異常,受查異常和非受查異常都可以被丟擲。
- throws 關鍵字用在方法宣告上,可以丟擲多個異常,用來標識該方法可能丟擲的異常列表。一個方法用 throws 標識了可能丟擲的異常列表,呼叫該方法的方法中必須包含可處理異常的程式碼,否則也要在方法簽名中用 throws 關鍵字宣告相應的異常。
Java中的值傳遞和引用傳遞
- 值傳遞,意味著傳遞了物件的一個副本,即使副本被改變,也不會影響源物件。
- 引用傳遞,意味著傳遞的並不是實際的物件,而是物件的引用。因此,外部對引用物件的改變會反映到所有的物件上。
(未完待續)
(後續更新: 泛型、StringBuffer與StringBuilder、序列化與反序列化、==equalshashcode三劍客、靜態與非靜態)