一、接口的默认方法与静态方法,也就是接口中可以有实现方法
1 public classTest {2 public static voidmain(String[] args) {3 Formula a=newFor();4 a.calculate(1);5 System.out.println(a.sqrt(8));6
7
8 }9 interfaceFormula {10 double calculate(inta);11 default double sqrt(int a) {//这个方法可以在实现类重写,或者直接使用
12 returnMath.sqrt(a);13 }14 }15 static class For implementsFormula{16 @Override17 public double calculate(inta) {18 return 0;19 }20
21 @Override22 public double sqrt(inta) {23 return 0;24 }25 }26 }
1 packagecom.ming.jdk18;2
3
4 /**
5 *6 *@authormingge7 * jdk1.8接口支持静态方法与默认方法8 *9 */
10 public interfaceTestInterface {11
12 //这个是默认方法
13 defaultString get(String aa,String bb){14 System.out.println("我是jdk1.8默认实现方法...");15 return "";16 }17
18 String aa="2222";19
20 //这个是静态方法
21 static void staticmethod(){System.out.println("我是静态方法"+aa);}22 }
1 packagecom.ming.jdk18;2
3
4 public classMain {5
6
7 public static voidmain(String[] args) {8 TestInterface.staticmethod();9 }10
11
12 }
以前的版本定义接口是不能有实现机制的,现在这样用了一个default关键字后,就可以实现,然后子类可以重写,也可以直接使用了。好处多多,感觉有点抽象类了...越来越灵活了。加入静态方法后,你以后的工具类就可以参考接口来设计啦.这是一个优点啦.
二、Lambda 表达式
1 public classTest {2 public static voidmain(String[] args) {3 List names = Arrays.asList("peter", "anna", "mike", "xenia");4 Collections.sort(names, new Comparator() {//java以前老版本的写法5 @Override6 public intcompare(String a, String b) {7 returnb.compareTo(a);8 }9 });10 for(String name:names){11 System.out.println(name);12 }13 }14
15 }
1 只需要给静态方法 Collections.sort 传入一个List对象以及一个比较器来按指定顺序排列。通常做法都是创建一个匿名的比较器对象然后将其传递给sort方法。2 在Java 8中你就没必要使用这种传统的匿名对象的方式了,Java 8提供了更简洁的语法,lambda表达式:3 复制代码 代码如下:4
5 Collections.sort(names, (String a, String b) -> {
6 return b.compareTo(a);
7 });8
9 看到了吧,代码变得更段且更具有可读性,但是实际上还可以写得更短:10 复制代码 代码如下:11
12 Collections.sort(names, (String a, String b) -> b.compareTo(a));13
14 对于函数体只有一行代码的,你可以去掉大括号{}以及return关键字,但是你还可以写得更短点:15 复制代码 代码如下:16
17 Collections.sort(names, (a, b) -> b.compareTo(a));18
19 Java编译器可以自动推导出参数类型,所以你可以不用再写一次类型。接下来我们看看lambda表达式还能作出什么更方便的东西来:
lambda表达式的使用简化了代码。
三、函数式接口与静态导入
Lambda表达式是如何在java的类型系统中表示的呢?每一个lambda表达式都对应一个类型,通常是接口类型。而“函数式接口”是指仅仅只包含一个抽象方法的接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。
因为默认方法不算抽象方法,所以你也可以给你的函数式接口添加默认方法。
我们可以将lambda表达式当作任意只包含一个抽象方法的接口类型,确保你的接口一定达到这个要求,你只需要给你的接口添加 @FunctionalInterface 注解,编译器如果发现你标注了这个注解的接口有多于一个抽象方法的时候会报错的。
1 public classTest {2 public static voidmain(String[] args) {3 Converter a = (from) ->Integer.valueOf(from);4
5 //Java 8 允许你使用 :: 关键字来传递方法或者构造函数引用
6 Converter converter = Integer::valueOf;//这个是静态方式导入
7
8 Integer m=a.convert("123");9 System.out.println(m);10 test test=mmm -> "aaaa";//mmm代表你要传入的参数
11 String testResult=test.aa("");//aa代表你要传入的方法
12 System.out.println(testResult);13 }14
15 @FunctionalInterface16 interface Converter{17 T convert(F from);18 }19
20 interfacetest{21 String aa(String mmm);22 }23
24 //使用函数式接口时,接口的定义只能有一个,@FunctionalInterface注解可有可无
25 }
四、Lambda 作用域
在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。
五、访问局部变量
1 public classTest {2 public static voidmain(String[] args) {3 final int num = 1;4 Converter stringConverter =
5 (from) -> String.valueOf(from +num);6 String str=stringConverter.convert(2);7 System.out.println(str);//输出38 //final关键字可以去掉,但是默认是存在的,所以,对num变量不能再次赋值修改
9 }10
11 @FunctionalInterface12 interface Converter{13 T convert(F from);14 }15
16 }
六、访问对象字段与静态变量
1 public classTest {2 public static voidmain(String[] args) {3 Lambda4 lambda4=newLambda4();4 lambda4.testScopes();5 }6
7 @FunctionalInterface8 interface Converter{9 T convert(F from);10 }11
12 static classLambda4 {13 static int outerStaticNum=0;14 int outerNum=0;15 voidtestScopes() {16 Converter stringConverter1 = (from) ->{17 outerNum = 23;18 returnString.valueOf(outerNum);19 };20 String a=stringConverter1.convert(outerNum);21 System.out.println(a);//输出23
22 Converter stringConverter2 = (from) ->{23 outerStaticNum = 72;24 returnString.valueOf(outerStaticNum);25 };26
27 }28 }29
30 //这里的意思是outerStaticNum与outerNum两个参数可以多次赋值
31
32 }