学习Java8新特性

时间:2023-01-31 12:56:00

一、允许给接口定义默认方法和静态方法

那么问题来了,

1、给接口定义的默认方法必须要用default关键字修饰,它是被定义为非抽象方法的,所以必须有方法体,即必须有方法的具体实现

1)如果是一个子类既继承了父类同时又实现了带有默认方法的接口,而父类和接口有相同的方法,子类应该是选择哪一个执行呢?实践是检验真理的唯一标准,通过代码来寻找答案吧。

定义一个带默认方法的接口MyInterface

 学习Java8新特性

 

定义一个父类Father

 学习Java8新特性

 

定义一个子类Son:

 学习Java8新特性

 

执行结果如上图,所以这种情况下,子类会选择来自父类的方法。

(2)如果同时实现了有相同默认方法的多个接口,这个时候实现类又会如何选择呢?

还是看代码:

另一个接口的定义如下OtherInterface

 学习Java8新特性

 

实现类报错了Son:

 学习Java8新特性

 

错误描述是:Duplicate default methods named greeting with the parameters () and () are inherited from the types OtherInterface and MyInterface
所以这种情况下实现类必须重写该方法。

正确实现如下:

 学习Java8新特性

 

2、静态方法必须要用static修饰,并且也是必须定义为非抽象方法的。

这里有必要解释一下在Java8以前接口方法不能定义为静态方法是什么含义。因为在Java8以前,接口中的方法都是抽象的,而静态方法是类方法,是不需要通过创建对象而通过类名直接调用的,抽象方法是没有方法体的,所以就没有办法执行了,所以也就不该能够被定义为静态方法了。

 

二、增加了函数式接口:有且仅有一个抽象方法的接口,但是可以有其他的非抽象方法(比如说默认方法和静态方法,因为默认方法和静态方法都不是抽象方法,正如新特性1中描述的那样)。还可以给接口添加@FunctionalInterface注解(是的,这里说的是可以而不是必须,所以@FunctionalInterface是可写可不写的),这样编译器如果发现接口标注了这个注解,有超过一个抽象方法或者没有定义抽象方法都会报错。

如下是错误的函数式接口的定义:

没有定义抽象方法:

 学习Java8新特性

 

定义了不止一个抽象方法:

 学习Java8新特性

 

以上两种错误的描述都是

Invalid '@FunctionalInterface' annotation; MyFunctionalInterface<T> is not a functional interface

这是使用了@FunctionalInterface来标识函数式接口的好处。

正确地定义一个函数式接口的例子如下:

 学习Java8新特性

三、引用了Lambda表达式

Lambda表达式的学习,它是如何写的?以及为什么要引入Lambda表达式,或者说引入它的意义又是什么?这些问题值得思考。

1、首先来了解Lambda表达式

Lambda表达式的语法格式是:

(parameters) -> expression

(parameters) ->{ statements; }

Lambda表达式有如下特征:

1)可选类型声明:参数类型可先可不写,如果不写,编译器会统一识别参数值

2)可选的参数圆括号:多个参数需要定义圆括号但一个参数可以不需要定义圆括号

3)可选的大括号:如果主体(expresstion/statements)只有一个语句,可以不需要用大括号

4)可选的return关键字:如果只有一个返回值表达式则可以省略掉return关键字

注意:

1)如果要给Lambda表达式的返回值赋值,返回值必须赋值给一个函数式接口,也就是说可以理解成整个Lambda表达式的返回值类型是一个函数式接口类型。

2)Lambda表达式可以作为方法的参数

3)Lambda表达式的常用场景是代替匿名内部类。

4)lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

5)在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

 

Java8新特性官网介绍:

http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html