diff --git a/README.en.md b/README.en.md deleted file mode 100644 index bd1cea73fc64669737f12649f63f9ba6755f1e38..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# java8-learn - -#### Description -JAVA 8 新特性学习项目 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index c64ea68491847ef9ab73e61a0bd56135329215d4..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# java8-learn - -#### 介绍 -JAVA 8 新特性学习项目 - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request diff --git a/src/test/java/com/wind/java8learn/interfacedefault/MyClass.java b/src/test/java/com/wind/java8learn/interfacedefault/MyClass.java new file mode 100644 index 0000000000000000000000000000000000000000..9955daeb7c6dde61070c53c1e7533505dd66bf72 --- /dev/null +++ b/src/test/java/com/wind/java8learn/interfacedefault/MyClass.java @@ -0,0 +1,12 @@ +package com.wind.java8learn.interfacedefault; + +/** + * @Author :wind + * @Description : + * @Date : 2020/1/7 9:59 + */ +public class MyClass { + public String getName(){ + return "嘿嘿嘿"; + } +} diff --git a/src/test/java/com/wind/java8learn/interfacedefault/MyFun.java b/src/test/java/com/wind/java8learn/interfacedefault/MyFun.java new file mode 100644 index 0000000000000000000000000000000000000000..54f7a66cc03774633699855b5923b62ee33acbaa --- /dev/null +++ b/src/test/java/com/wind/java8learn/interfacedefault/MyFun.java @@ -0,0 +1,13 @@ +package com.wind.java8learn.interfacedefault; + +/** + * @Author :wind + * @Description : + * @Date : 2020/1/6 17:59 + */ +public interface MyFun { + + default String getName(){ + return "哈哈哈"; + } +} diff --git a/src/test/java/com/wind/java8learn/interfacedefault/MyInterface.java b/src/test/java/com/wind/java8learn/interfacedefault/MyInterface.java new file mode 100644 index 0000000000000000000000000000000000000000..6976cd4fbf111dedfb6b1fc66e117c47b008b997 --- /dev/null +++ b/src/test/java/com/wind/java8learn/interfacedefault/MyInterface.java @@ -0,0 +1,20 @@ +package com.wind.java8learn.interfacedefault; + +/** + * @Author :wind + * @Description : java8 之后,接口中: + * 1、可以有default修饰的有方法体的方法 + * 2、可以有方法体的静态方法 + * @Date : 2020/1/7 10:02 + */ +public interface MyInterface { + + default String getName(){ + return "呵呵呵"; + } + + public static void show(){ + System.out.println("接口中的静态方法"); + } + +} diff --git a/src/test/java/com/wind/java8learn/interfacedefault/SubClass.java b/src/test/java/com/wind/java8learn/interfacedefault/SubClass.java new file mode 100644 index 0000000000000000000000000000000000000000..5f0dcce2211f7f4f0c7d258f44e98cfa54931b58 --- /dev/null +++ b/src/test/java/com/wind/java8learn/interfacedefault/SubClass.java @@ -0,0 +1,18 @@ +package com.wind.java8learn.interfacedefault; + +/** + * @Author :wind + * @Description : 子类 + * 继承父类(有default方法)和实现接口(有default方法): + * 1、继承父类和实现接口时,都包含相同默认的方法时,父类的默认方法优先调用 + * 2、不继承父类,实现了多个带相同默认方法时,必须在子类重写哪个接口的方法 + * + * @Date : 2020/1/7 10:04 + */ +public class SubClass /*extends MyClass*/ implements MyFun,MyInterface { + + @Override + public String getName() { + return MyInterface.super.getName(); + } +} diff --git a/src/test/java/com/wind/java8learn/interfacedefault/TestDefaultInterface.java b/src/test/java/com/wind/java8learn/interfacedefault/TestDefaultInterface.java new file mode 100644 index 0000000000000000000000000000000000000000..9e52914b1071b0e154648360e730c96737f0f087 --- /dev/null +++ b/src/test/java/com/wind/java8learn/interfacedefault/TestDefaultInterface.java @@ -0,0 +1,15 @@ +package com.wind.java8learn.interfacedefault; + +/** + * @Author :wind + * @Description : DefaultInterface测试 + * @Date : 2020/1/7 10:06 + */ +public class TestDefaultInterface { + + public static void main(String[] args) { + SubClass sc = new SubClass(); + System.out.println(sc.getName()); + MyInterface.show(); + } +} diff --git a/src/test/java/com/wind/java8learn/localdate/DateFormatThreadLocal.java b/src/test/java/com/wind/java8learn/localdate/DateFormatThreadLocal.java new file mode 100644 index 0000000000000000000000000000000000000000..01f9ecf4f0f0fa3dd065020a12c51b98a38c7a3b --- /dev/null +++ b/src/test/java/com/wind/java8learn/localdate/DateFormatThreadLocal.java @@ -0,0 +1,24 @@ +package com.wind.java8learn.localdate; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @Author :wind + * @Description : + * @Date : 2020/1/7 14:15 + */ +public class DateFormatThreadLocal { + + private static final ThreadLocal df = new ThreadLocal(){ + protected DateFormat initialValue(){ + return new SimpleDateFormat("yyyyMMdd"); + } + }; + + public static final Date convert(String source) throws ParseException { + return df.get().parse(source); + } +} diff --git a/src/test/java/com/wind/java8learn/localdate/TestLocalDateTime.java b/src/test/java/com/wind/java8learn/localdate/TestLocalDateTime.java new file mode 100644 index 0000000000000000000000000000000000000000..5843322cc3114a31a485fd726d12d2962c0483be --- /dev/null +++ b/src/test/java/com/wind/java8learn/localdate/TestLocalDateTime.java @@ -0,0 +1,166 @@ +package com.wind.java8learn.localdate; + +import org.junit.Test; + +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAdjusters; +import java.util.Set; + +/** + * @Author :wind + * @Description : + * @Date : 2020/1/7 14:49 + */ +public class TestLocalDateTime { + + /** + * 1、LocalDate、LocalTime、LocalDateTime + */ + @Test + public void test1(){ + LocalDateTime ldt = LocalDateTime.now(); + System.out.println(ldt); + + LocalDateTime ld2 = LocalDateTime.of(2020, 01, 07, 14, 52, 10); + System.out.println(ld2); + + LocalDateTime ldt3 = ld2.plusYears(20);//加20年 + System.out.println(ldt3); + + LocalDateTime ld4 = ld2.minusMonths(2); + System.out.println(ld4); + + System.out.println(ldt.getYear()); + System.out.println(ldt.getMonthValue()); + System.out.println(ldt.getDayOfMonth()); + System.out.println(ldt.getHour()); + System.out.println(ldt.getMinute()); + System.out.println(ldt.getSecond()); + + } + + /** + * 2、Instant : 时间戳。 (使用 Unix 元年 1970年1月1日 00:00:00 所经历的毫秒值) + */ + @Test + public void test2(){ + Instant ins = Instant.now(); //默认使用 UTC 时区,北京时间比UTC时区领先8个小时 + System.out.println(ins); + + OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8)); + System.out.println(odt); + + System.out.println(ins.getNano()); + + Instant ins2 = Instant.ofEpochSecond(5); + System.out.println(ins2); + + } + + /** + * 3、Duration:用于计算两个【时间】间隔 + * Period:用于计算两个【日期】间隔 + */ + @Test + public void test3(){ + Instant ins1 = Instant.now(); + + System.out.println("----------------"); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Instant ins2 = Instant.now(); + System.out.println("所耗费的时间为: " + Duration.between(ins1,ins2)); + + System.out.println("---------------"); + + LocalDate ld1 = LocalDate.now(); + LocalDate ld2 = LocalDate.of(2000,1,1); + Period pe = Period.between(ld2,ld1); + System.out.println(pe.getYears()); + System.out.println(pe.getMonths()); + System.out.println(pe.getDays()); + } + + /** + * 时间校正器:TemporalAdjuster + */ + @Test + public void test4(){ + LocalDateTime ldt = LocalDateTime.now(); + System.out.println(ldt); + + LocalDateTime ldt2 = ldt.withDayOfMonth(10); + System.out.println(ldt2); + + LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)); + System.out.println(ldt3); + + System.out.println("---------------------"); + /** + * 自定义:下一个工作日 + */ + LocalDate ld = LocalDate.now();//当前日期 + //下一个工作日 + LocalDate ldt5 = ld.with((l) -> { + LocalDate ldt4 = (LocalDate)l; + System.out.println("今天是:"+ ldt4); + DayOfWeek dow = ldt4.getDayOfWeek(); + //若今天是周五,则下个工作日在今天日期基础上 +3 + if(dow.equals(DayOfWeek.FRIDAY)){ + return ldt4.plusDays(3); + //若今天是周六,则下个工作日在今天日期基础上 +2 + }else if(dow.equals(DayOfWeek.SATURDAY)){ + return ldt4.plusDays(2); + }else{ + //若今天既不是周六也不是周日,则下个工作日在今天日期基础上 +1 + return ldt4.plusDays(1); + } + }); + System.out.println("下一个工作日是:" + ldt5); + } + + /** + * 5、DateTimeFormatter : 解析和格式化日期或时间 + */ + @Test + public void test5(){ + DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E"); + LocalDateTime ldt = LocalDateTime.now(); + String strDate = ldt.format(dateTimeFormatter); + System.out.println(strDate); + LocalDateTime newLdt = ldt.parse(strDate, dateTimeFormatter); + System.out.println(newLdt); + } + + //6.ZonedDate、ZonedTime、ZonedDateTime : 带时区的时间或日期 + @Test + public void test7(){ + LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai")); + System.out.println(ldt); + + ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("US/Pacific")); + System.out.println(zdt); + } + @Test + public void test6(){ + Set set = ZoneId.getAvailableZoneIds(); + set.forEach(System.out::println); + } + + + + + + + + + + + + +} diff --git a/src/test/java/com/wind/java8learn/localdate/TestSimpleDateFormat.java b/src/test/java/com/wind/java8learn/localdate/TestSimpleDateFormat.java new file mode 100644 index 0000000000000000000000000000000000000000..938734999ee56c25cb5439ff19f8e6cda68a1c7f --- /dev/null +++ b/src/test/java/com/wind/java8learn/localdate/TestSimpleDateFormat.java @@ -0,0 +1,85 @@ +package com.wind.java8learn.localdate; + +import org.junit.Test; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.concurrent.*; + +/** + * @Author :wind + * @Description : + * @Date : 2020/1/7 14:03 + */ +public class TestSimpleDateFormat { + + @Test + public void test1() throws ExecutionException, InterruptedException { + /*SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); + Callable task = new Callable(){ + @Override + public Date call() throws Exception{ + return sdf.parse("20200117"); + } + }; + ExecutorService pool = Executors.newFixedThreadPool(10); + List> results = new ArrayList<>(); + for(int i = 0;i <10 ;i++){ + results.add(pool.submit(task)); + } + for(Future future : results){ + System.out.println(future.get()); + } + pool.shutdown();*/ + + //解决多线程安全问题 + /*Callable task2 = new Callable() { + @Override + public Date call() throws Exception { + return DateFormatThreadLocal.convert("20161121"); + } + }; + + ExecutorService pool2 = Executors.newFixedThreadPool(10); + + List> results2 = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + results2.add(pool2.submit(task2)); + } + for (Future future : results2) { + System.out.println(future.get()); + } + pool2.shutdown();*/ + + DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd"); + + Callable task3 = new Callable() { + @Override + public LocalDate call() throws Exception { + LocalDate ld = LocalDate.parse("20161121", dtf); + return ld; + } + }; + + ExecutorService pool3 = Executors.newFixedThreadPool(10); + + List> results3 = new ArrayList<>(); + + for (int i = 0; i < 10; i++) { + results3.add(pool3.submit(task3)); + } + + for (Future future : results3) { + System.out.println(future.get()); + } + + pool3.shutdown(); + } + + +} diff --git a/src/test/java/com/wind/java8learn/model/Employee.java b/src/test/java/com/wind/java8learn/model/Employee.java index 89d3be3217c48154d825d106cb0f4a0ee3314f57..bdd505a515a1a905d031a4528703031dd6f25375 100644 --- a/src/test/java/com/wind/java8learn/model/Employee.java +++ b/src/test/java/com/wind/java8learn/model/Employee.java @@ -1,9 +1,6 @@ package com.wind.java8learn.model; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; +import lombok.*; import java.util.Objects; @@ -15,6 +12,7 @@ import java.util.Objects; @Data @RequiredArgsConstructor @AllArgsConstructor +@NoArgsConstructor public class Employee { @NonNull diff --git a/src/test/java/com/wind/java8learn/model/ForkJoinCalculate.java b/src/test/java/com/wind/java8learn/model/ForkJoinCalculate.java new file mode 100644 index 0000000000000000000000000000000000000000..567cc9ce772a0be01585a9a155b08a329abe4f35 --- /dev/null +++ b/src/test/java/com/wind/java8learn/model/ForkJoinCalculate.java @@ -0,0 +1,38 @@ +package com.wind.java8learn.model; + +import java.util.concurrent.RecursiveTask; + +/** + * @Author :wind + * @Description : + * @Date : 2020/1/6 11:05 + */ +public class ForkJoinCalculate extends RecursiveTask { + + private static final long serialVersionUID = 4271197421655045692L; + + private long start; + + private long end; + + private static final long THRESHOLD = 10000; + + @Override + protected Long compute() { + long length = end - start; + if(length <=THRESHOLD ){ + long sum = 0; + for(long i = start;i<=end;i++){ + sum+=i; + } + + } + + return null; + } + + + + + +} diff --git a/src/test/java/com/wind/java8learn/model/Godness.java b/src/test/java/com/wind/java8learn/model/Godness.java new file mode 100644 index 0000000000000000000000000000000000000000..7ffc6469ad52a204263c28dee7d058f6b1aa0ae8 --- /dev/null +++ b/src/test/java/com/wind/java8learn/model/Godness.java @@ -0,0 +1,14 @@ +package com.wind.java8learn.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Godness { + + private String name; + +} diff --git a/src/test/java/com/wind/java8learn/model/Man.java b/src/test/java/com/wind/java8learn/model/Man.java new file mode 100644 index 0000000000000000000000000000000000000000..de8037213b040bc218767f346995930c6d6f9040 --- /dev/null +++ b/src/test/java/com/wind/java8learn/model/Man.java @@ -0,0 +1,13 @@ +package com.wind.java8learn.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Man { + + private Godness god; +} diff --git a/src/test/java/com/wind/java8learn/model/NewMan.java b/src/test/java/com/wind/java8learn/model/NewMan.java new file mode 100644 index 0000000000000000000000000000000000000000..4fb1e5e54ac051d2204a557d94c79b0f7d285ef7 --- /dev/null +++ b/src/test/java/com/wind/java8learn/model/NewMan.java @@ -0,0 +1,36 @@ +package com.wind.java8learn.model; + +import java.util.Optional; + +//注意:Optional 不能被序列化 +public class NewMan { + + private Optional godness = Optional.empty(); + + private Godness god; + + public Optional getGod(){ + return Optional.of(god); + } + + public NewMan() { + } + + public NewMan(Optional godness) { + this.godness = godness; + } + + public Optional getGodness() { + return godness; + } + + public void setGodness(Optional godness) { + this.godness = godness; + } + + @Override + public String toString() { + return "NewMan [godness=" + godness + "]"; + } + +} diff --git a/src/test/java/com/wind/java8learn/streamapi/StreamAPIEndTest.java b/src/test/java/com/wind/java8learn/streamapi/StreamAPIEndTest.java index b884e42608fd832d1900a5199105f3d4b696b78c..afe63722831503222ef4330620f061b84fc3d5b2 100644 --- a/src/test/java/com/wind/java8learn/streamapi/StreamAPIEndTest.java +++ b/src/test/java/com/wind/java8learn/streamapi/StreamAPIEndTest.java @@ -1,7 +1,6 @@ package com.wind.java8learn.streamapi; import com.wind.java8learn.model.Employee; -import lombok.NonNull; import org.junit.jupiter.api.Test; import java.util.Arrays; diff --git a/src/test/java/com/wind/java8learn/streamapi/StreamAPIOptionalTest.java b/src/test/java/com/wind/java8learn/streamapi/StreamAPIOptionalTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3cf603b73dad0f968a682cd5ed91a97d7e151dfe --- /dev/null +++ b/src/test/java/com/wind/java8learn/streamapi/StreamAPIOptionalTest.java @@ -0,0 +1,115 @@ +package com.wind.java8learn.streamapi; + +import com.wind.java8learn.model.Employee; +import com.wind.java8learn.model.Godness; +import com.wind.java8learn.model.Man; +import com.wind.java8learn.model.NewMan; +import org.junit.Test; + +import java.util.Optional; + +/** + * @Author :wind + * @Description : Optional 是一个容器类,代表一个值存在或者不存在,原来用null表示一个值不存在,现在用Optional表达这个概念。并且可以避免空指针异常 + * @Date : 2020/1/6 14:09 + */ +public class StreamAPIOptionalTest { + + /** + * Optional容器类的常用方法: + * 1、Optional.of(T t):创建一个Optional实例 + * 2、Optional.empty() : 创建一个空的 Optional 实例 + * 3、Optional.ofNullable(T t):若 t 不为 null,创建 Optional 实例,否则创建空实例 + * 4、isPresent() : 判断是否包含值 + * 5、orElse(T t) : 如果调用对象包含值,返回该值,否则返回t + * 6、orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值 + * 7、map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty() + * 8、flatMap(Function mapper):与 map 类似,要求返回值必须是Optional + */ + + @Test + public void test1(){ + Optional op = Optional.of(new Employee()); + System.out.println(op.get()); + } + + @Test + public void test2(){ + Optional op = Optional.ofNullable(null); + Optional emptyOpt = Optional.empty(); + System.out.println(emptyOpt.isPresent()); + } + + @Test + public void test3(){ + Optional optionalEmployee = Optional.ofNullable(null); + /*if(optionalEmployee.isPresent()){ + System.out.println(optionalEmployee.get()); + }*/ + Employee employee = optionalEmployee.orElse(new Employee("张三", 28, 17110.0)); + System.out.println("employee :"+employee); + + Employee employee1 = optionalEmployee.orElseGet(() -> new Employee()); + System.out.println("employee1 :"+employee1); + } + + @Test + public void test4(){ + Optional op = Optional.of(new Employee("张三",26, 9999.99, Employee.Status.FREE)); + + Optional op2 = op.map(Employee::getName); + System.out.println(op2.get()); + + Optional op3 = op.flatMap((e) -> Optional.of(e.getName())); + System.out.println(op3.get()); + } + + //需求:获取一个男人心中女神的名字 + /** + * 常规方法 + * @param man + * @return + */ + public String getGodnessName(Man man){ + if(man != null){ + Godness g = man.getGod(); + if(g != null){ + return g.getName(); + } + } + return "苍老师"; + } + + /** + * 使用Optional方法,避免多重判断 + * @return + */ + @Test + public void test6(){ + Optional godness = Optional.ofNullable(new Godness("林志玲")); + Optional op = Optional.ofNullable(new NewMan(godness)); + String name = getGodnessName2(op); + System.out.println(name); + } + + public String getGodnessName2(Optional man){ + return man.orElse(new NewMan()) + .getGodness() + .orElse(new Godness("cang老师")) + .getName(); + } + + + + + + + + + + + + + + +} diff --git a/src/test/java/com/wind/java8learn/streamapi/StreamAPIStreamTest.java b/src/test/java/com/wind/java8learn/streamapi/StreamAPIStreamTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5f89ef084ff4b4ae3aedf6cd3abc133f8ca0a884 --- /dev/null +++ b/src/test/java/com/wind/java8learn/streamapi/StreamAPIStreamTest.java @@ -0,0 +1,12 @@ +package com.wind.java8learn.streamapi; + +/** + * @Author :wind + * @Description : Stream API 并行流与顺序流 + * @Date : 2020/1/6 10:51 + */ +public class StreamAPIStreamTest { + + + +} diff --git a/src/test/java/com/wind/java8learn/streamapi/StreamAPITransactionTest.java b/src/test/java/com/wind/java8learn/streamapi/StreamAPITransactionTest.java index ac2a2a9eeed8d02a557806ec3ca2d65729b5f536..5fe28363e84fe1892d80e9e981732fff12686338 100644 --- a/src/test/java/com/wind/java8learn/streamapi/StreamAPITransactionTest.java +++ b/src/test/java/com/wind/java8learn/streamapi/StreamAPITransactionTest.java @@ -99,7 +99,7 @@ public class StreamAPITransactionTest { System.out.println("----纯字母排序-----"); transactions.stream() - .map((t) -> t.getTrader().getName()) + .map( t -> t.getTrader().getName()) .flatMap(StreamAPITransactionTest::filterCharacter) .sorted((s1, s2) -> s1.compareToIgnoreCase(s2)) .forEach(System.out::print); diff --git "a/\351\241\271\347\233\256\350\257\264\346\230\216README.md" "b/\351\241\271\347\233\256\350\257\264\346\230\216README.md" new file mode 100644 index 0000000000000000000000000000000000000000..8fc022b22d07d8dd5751cb82821abc2e7d4a8fc5 --- /dev/null +++ "b/\351\241\271\347\233\256\350\257\264\346\230\216README.md" @@ -0,0 +1,24 @@ +# java8-learn + +#### 简介:JAVA 8 新特性学习项目 + +##### 概要: + +1. Lambda表达式(暂无) + +2. Stream API (重点) + +3. Optional + +4. 接口的default方法,接口的静态方法 + +5. LocalDate + +6. 如何使用重复注解 + + ------ + +##### 说明 + +本项目为java8新特性的练习项目,所有代码放在test包内,包含每个重要知识点的单元测试 +