一、重點(diǎn)知識(shí)
注解并無(wú)主動(dòng)功能,主要功能就是給類和類的組成做標(biāo)記,讓編譯器檢查
RetentionPolicy.CLASS是默認(rèn)生命周期,沒(méi)有被@Retention修飾的注解的生命周期都是這種策略。
接口中default方法只能讓實(shí)現(xiàn)類用
static 定義的方法只能給接口用
接口中只有一個(gè)抽象方法時(shí),才可以用lambda表達(dá)式簡(jiǎn)寫,這樣的接口我們稱為函數(shù)式接口
只有有提示的時(shí)候編譯器才能給lambda表達(dá)式補(bǔ)全
函數(shù)接口實(shí)現(xiàn)匿名內(nèi)部類的簡(jiǎn)寫形式就是lambda表達(dá)式
lambda表達(dá)式不能調(diào)用接口中的默認(rèn)方法
異常最重要的是名稱,處理都以異常名為準(zhǔn)
二、重點(diǎn)問(wèn)題
注解部分重點(diǎn)內(nèi)容:
1、什么是注解,注解的作用
2、如何自定義一個(gè)注解
3、三種重要的元注解
@target規(guī)定了注解的使用位置 @retention 規(guī)定注解的生命周期 @Repeatable 定義重復(fù)注解
4、注解在實(shí)際中如何通過(guò)反射調(diào)用
三課堂知識(shí)
注解
- 定義:
- 注解就是給代碼中的某個(gè)成員做一個(gè)標(biāo)記
- 至于能不能發(fā)揮作用,主要看檢測(cè)這個(gè)標(biāo)記的功能
- 自定義注解
- 寫一個(gè)類, @interface
- 元注解 : 用來(lái)給標(biāo)記注解
- @Target : 當(dāng)前定義的注解以后可以使用在什么位置
- @Retention : 當(dāng)前注解保留到什么時(shí)候
一. default關(guān)鍵字
-
定義
- 1.8中允許我們給接口添加一個(gè)非抽象的方法實(shí)現(xiàn), 在方法使用default關(guān)鍵字就可以了,這個(gè)特征又叫做拓展方法
-
演示
public interface MyInterface { //使用default的關(guān)鍵字 public default void method(){ System.out.println("你好...."); } } -
注意事項(xiàng)
- 我們都知道, java之所以支持多實(shí)現(xiàn)就是應(yīng)為接口中沒(méi)有具體的邏輯代碼, 不會(huì)造成沖突的問(wèn)題, 那么1.8之后我們可以在接口中編寫具體的邏輯代碼了,那么多實(shí)現(xiàn)的時(shí)候會(huì)沖突嗎 ?
- 肯定會(huì)沖突的,所以為了解決這個(gè)問(wèn)題, 編譯器要求如果多實(shí)現(xiàn)的時(shí)候出現(xiàn)了相同名稱的非抽象方法的話,子類就必須重寫這個(gè)方法
-
多實(shí)現(xiàn)
public class Demo implements MyInterface,MyInterface2{ @Override public void method() { System.out.println("子類必須重寫多個(gè)接口中相同名稱的非抽象方法"); MyInterface.super.method(); } }
二. 接口中的靜態(tài)方法
-
定義
- 在接口中定義一個(gè)靜態(tài)的方法, 可以有具體的代碼實(shí)現(xiàn)
-
演示
public interface MyInterface { //靜態(tài)方法 只能接口自己使用 //接口中的靜態(tài)方法權(quán)限必須是public的, 默認(rèn)加上public static void method3(){ System.out.println("我是接口中的靜態(tài)方法"); } } -
注意事項(xiàng)
- 子類無(wú)法使用接口中的靜態(tài)方法
- 接口中的靜態(tài)方法的權(quán)限必須是公共的,可以不寫,默認(rèn)是公共的
三. lambda表達(dá)式
-
定義
- 一種簡(jiǎn)寫形式,格式精簡(jiǎn), 很酷
- 每一個(gè)lambda的表達(dá)都對(duì)應(yīng)一個(gè)類型,通常是接口類型的
- 適用于函數(shù)式接口(只有一個(gè)抽象方法的接口)
-
格式
- (參數(shù)...) -> {執(zhí)行代碼} 返回一個(gè)可用的對(duì)象
- 當(dāng)只有一句代碼時(shí),大括號(hào)可以省略, 不建議省略
-
演示
public static void main(String[] args) { List<String> list = Arrays.asList("hh","dd","ni","kk"); //之前的寫法 Collections.sort(list,new Comparator<String>() { public int compare(String o1, String o2) { return o1.compareTo(o2); } }); //lambda表達(dá)式的寫法 Collections.sort(list, (String a,String b)->{ return a.compareTo(b); }); System.out.println(list); } -
方法的引用
- 使用 : : 來(lái)引用一個(gè)類的方法
public interface Doing<K,T> { public T doing(K k); }public static void main(String[] args) { //調(diào)用類中的靜態(tài)方法來(lái)處理接口中方法上的參數(shù) Doing<String, Integer> d = Integer::valueOf; Integer integer = d.doing("123"); System.out.println(integer); }public static void main(String[] args) { //調(diào)用對(duì)象的方法 Doing<String, Integer> d = "java"::lastIndexOf; Integer i = d.doing("v"); System.out.println(i); } -
構(gòu)造方法的引用
- 用new關(guān)鍵字來(lái)代替構(gòu)造方法
public class Person { String name; Person(String name) { super(); this.name = name; } @Override public String toString() { return "Person [name=" + name + "]"; } }public static void main(String[] args) { //引用對(duì)象的構(gòu)造方法 Doing<String, Person> d = Person::new; Person person = d.doing("小明"); System.out.println(person); } -
注意事項(xiàng)
- lambda表達(dá)式指向的接口必須和調(diào)用的方法的參數(shù)一致,也就是說(shuō)相當(dāng)于是接口實(shí)現(xiàn)類中的方法調(diào)用你指向的方法
- lambda表達(dá)式中訪問(wèn)外層作用域和老版本的匿名對(duì)象的方式很相似, 你可以直接訪問(wèn)標(biāo)記了final的外層局部變量, 或者示例的字段以及靜態(tài)變量
- lambda表達(dá)式中無(wú)法訪問(wèn)接口中的默認(rèn)方法(就是被default修飾的方法)
四. Stream接口
-
定義
- 表示能應(yīng)用在一組元素上一次執(zhí)行的操作序列
- 其實(shí)就是找了一個(gè)地方將執(zhí)行了某個(gè)方法后剩下的元素存放起來(lái)
- 提供了許多操作集合的方法,而且原集合數(shù)據(jù)不受影響
-
常用的方法
- filter 過(guò)濾
- sorted 排序
- map 轉(zhuǎn)化
- match 匹配
- count 計(jì)數(shù)
-
演示
public static void main(String[] args) { List<String> stringCollection = new ArrayList<>(); stringCollection.add("ddd2"); stringCollection.add("aaa2"); stringCollection.add("bbb1"); stringCollection.add("aaa1"); stringCollection.add("bbb3"); stringCollection.add("ccc"); stringCollection.add("bbb2"); stringCollection.add("ddd1"); //過(guò)濾出以a開(kāi)頭的元素并遍歷 stringCollection.stream(). filter((s)->s.startsWith("a")) .forEach(System.out::println);; } -
并行
- 并行Stream可以在多個(gè)線程上同時(shí)執(zhí)行
public static void main(String[] args) { int max = 1000000; List<String> values = new ArrayList<>(max); for (int i = 0; i < max; i++) { //創(chuàng)建隨機(jī)id UUID uuid = UUID.randomUUID(); values.add(uuid.toString()); } long t1 = System.nanoTime(); //獲取并行的stream long count = values.parallelStream().sorted().count(); System.out.println(count); long t2 = System.nanoTime(); System.out.println(t2-t1); }
五. Date
-
定義
- java 8 在包java.time下包含了一組全新的時(shí)間日期API
-
ZoneId
- 定義時(shí)區(qū)
public static void main(String[] args) { System.out.println(ZoneId.getAvailableZoneIds()); //獲取某個(gè)城市的時(shí)區(qū) ZoneId zone1 = ZoneId.of("Europe/Berlin"); ZoneId zone2 = ZoneId.of("Asia/Shanghai"); System.out.println(zone1.getRules()); System.out.println(zone2.getRules()); } -
LocalTime
- 一個(gè)沒(méi)有時(shí)區(qū)信息的時(shí)間,以設(shè)置的時(shí)區(qū)為準(zhǔn)備
public static void main(String[] args) { //獲取所有的時(shí)區(qū)信息 System.out.println(ZoneId.getAvailableZoneIds()); //獲取某個(gè)城市的時(shí)區(qū) ZoneId zone1 = ZoneId.of("Europe/Berlin"); ZoneId zone2 = ZoneId.of("Asia/Shanghai"); LocalTime now1 = LocalTime.now(zone1); LocalTime now2 = LocalTime.now(zone2); //判斷時(shí)間1以是否在時(shí)間2之前 System.out.println(now1.isBefore(now2)); // true //使用ChronoUnit計(jì)算兩個(gè)時(shí)間差值 long hoursBetween = ChronoUnit.HOURS.between(now1, now2); long minutesBetween = ChronoUnit.MINUTES.between(now1, now2); System.out.println(hoursBetween); System.out.println(minutesBetween); }
六.其他新特性
- 重復(fù)注解
- 可以將參數(shù)的名字保留到字節(jié)碼中
- Nashorn引擎 : jjs , 可以執(zhí)行js代碼
- 移除了FermGen空間,用Metaspace代替
- -XX:MetaSpaceSize與-XX:MaxMetaspaceSize被代替-XX:PermSize與-XX:MaxPermSize