inner class
其實內部類別簡單而言,就是一個 class 裡面再定義另外一個 class。基本上這個內部的 class 是拿來輔助之用,通常會宣告成 private。所以內部可以讀到外部的資料,但外部不需要知道內部在幹嘛。
anonymous class
其實這個概念也是一直似懂非懂。anonymous class 在 java 裡是非常常見的物件實體化方式,例如:
class ClassA {
}
public class MainClass{
public static void main(String[] args) {
ClassA a = new ClassA() { //實體化匿名類別
public void function1(int x, int y) {
System.out.println(x + y);
}
public int function2(int x) {
return x + 1;
}
};
}
}
像譬如在刷 leetcode 都會重寫 Comparator:
Queue<Integer> queue = new PriorotyQueue<>(new Comparator<Integer>(){
public int compare(Integer i1, Integer i2) {
return i2 - i1;
}
});
這其實就是一種用 anonymous class 的方式來實作 Comparator interface。
lambda expression
在Java 8之後,導入了Lambda語法,或者可以稱為Lambda表示式。如果說Lambda語法是用來表示一個匿名類別的話,那就不太正確了。實際上Lambda語法只能用來表示一個「只擁有一個方法的介面」所實作出來的匿名類別,但這樣講也是不太正確,在文章之後會進行觀念的改正,現在姑且先將其認知成這樣。
「只擁有一個方法的介面」在Java中很常使用到,例如執行緒的Runnable介面只擁有一個run方法,或是AWT的ActionListener只擁有一個actionPerformed方法。這類介面,都可以直接使用Lambda,將它們擁有的那單個方法快速實作出來。在Java 8之前,我們將這類的介面稱為Single Abstract Method type(SAM);在Java 8之後,因為這類的介面變得十分重要,所以將其另稱為Functional Interface。
Lambda 的使用情境:取代 functional interface 產生出的匿名類別。 在Java中,許多只有一個方法的介面,如果要使用這些介面,往往需要使用到至少4行程式碼才有辦法達成,舉例:
Runnable runnbale = new Runnable() {
public void run() {
System.out.println("run me!");
}
};
但用了 lambda 表達式,會變成:
Runnable runnbale = () -> System.out.println("run me!");
使用Lambda來取代以往Functional Interface的使用方式,可以大大的縮短程式碼,在編譯的過程中,也可以避免掉產生新的.class檔案出來,執行的時候,也不會再重新new出一個物件實體,而是直接將Lambda的body程式碼存放在記憶體,直接以類似call function的方式去執行,大大的提升程式的執行效能。