一、匿名內部類
匿名內部類是一種沒有名稱的類,多用于只使用一次的情況,本質上就是其所繼承的父類或接口的一個子類。
(一)繼承普通類的情況
public class Test{public void method(){System.out.println("通用方法");}public static void main(String[] args){Test ts1=new Test();ts1.method(); //調用普通方法
//創建內部類,等價于Test的一個子類,同時將其實例化為ts2Test ts2=new Test(){public void method(){System.out.println("內部類方法");}};ts2.method(); //調用內部類方法}
}
(二)繼承抽象類的情況
public abstract class Test{public abstract void method(String a);
}
public class TT{public static void main(String[] args){Test ts=new Test(){public void method(String a){System.out.println(a);}};ts.method();}
}
?本案例中,ts 本質上就是抽象類 Test 的一個子類的實例化對象,在匿名內部類中對抽象類 Test 中的 method 方法進行重寫,然后調用。
(三)繼承接口的情況
public interface Test{public void method(int a,int b);
}
public class TT{public static void main(String[] args){Test ts=new Test(){public void method(int a,int b){System.out.println(a+b);}};ts.method();}
}
?繼承接口的情況與繼承抽象類的情況類似,ts 仍然相當于接口 Test 的一個子類的實例化對象,重寫方法后,用這個子類的實例化對象 ts 去調用這個子類的方法 method。
二、Lambda表達式
在很多情況下,匿名內部類的書寫過于繁瑣,此時可以用 Lambda 表達式代替,其語法格式為:()->{}。對應上述三種情況,代碼更改如下:
(一)繼承普通類的情況
public class Test{public void method(){System.out.println("通用方法");}public static void main(String[] args){Test ts1=new Test();ts1.method(); //調用普通方法
//創建內部類,等價于Test的一個子類,同時將其實例化為ts2Test ts2=()->{System.out.println("內部類方法");};ts2.method(); //調用內部類方法}
}
(二)繼承抽象類的情況
public abstract class Test{public abstract void method(String a);
}
public class TT{public static void main(String[] args){Test ts=(String a)->{System.out.println(a);};ts.method();}
}
(三)繼承接口的情況
public interface Test{public void method(int a,int b);
}
public class TT{public static void main(String[] args){Test ts=(int a,int b)->{System.out.println(a+b);};ts.method();}
}
三、精簡 Lambda 表達式
① 參數類型可以省略
② 如果只有一個參數,() 可以省略
③ 如果方法體只有一條語句,{} 可以省略
④ 如果方法體中唯一的一條語句是 return 語句,省略 {} 的同時,return 關鍵字也要省略
對應上述三種情況,代碼可進一步優化為:
Test ts2=()->System.out.println("內部類方法");
Test ts=a->System.out.println(a);
Test ts=(a,b)->System.out.println(a+b);