From e50f9695bd8199c4f439b83c073c3c2ab3637ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Thu, 20 May 2021 21:09:52 +0800 Subject: [PATCH] =?UTF-8?q?enhance:=E5=A2=9E=E5=8A=A0=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/_posts/nf-java8.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source/_posts/nf-java8.md b/source/_posts/nf-java8.md index 0a5b0a9..da0f6bf 100644 --- a/source/_posts/nf-java8.md +++ b/source/_posts/nf-java8.md @@ -103,6 +103,30 @@ something.needSimpleOne(message -> { return doSomething(); }) Lambda表达式只能引用使用`final`标记的外层局部变量,即定义在定义Lambda表达式作用域以外的变量。但Lambda表达式可以直接使用与Lambda表达式同作用域的变量而不需要使用`final`标记。Lambda表达式的参数名不能与同作用域的局部变量重名,而且Lambda表达式也不能修改所有外部局部变量的值。 +## 方法引用 + +在引入Lambda表达式以后,就经常可能会出现下面这种形式的代码。 + +```java +bool hasStaff = userList.stream().anyMatch(user -> user.isStaff()); +``` + +这种形式的代码十分的啰嗦,而且并不美观。为了解决这个问题,Java 8引入了操作符`::`来提供对于方法的引用。所以借助方法引用操作符,就可以把上面这个示例修改成下面的样子。 + +```java +bool hasStaff = userList.stream().anyMatch(user::isStaff); +``` + +虽然在这个示例中还不太能看出来这个方法引用操作符的优势,但是它可以将原本必能复杂繁琐的代码进行简化,使代码的逻辑更加容易看清楚。 + +`::`方法引用操作符除了可以应用在对象实例上,还可以应用在以下这些对象上。 + +- 调用类中的静态方法:`ClassName::methodName`。 +- 调用类实例中的方法:`instanceName::methodName`。 +- 针对特定类的任意实例调用方法:`Class::methodName`。 +- 调用类自身(`this`)的方法:`this::methodName`。 +- 调用类的构造函数:`ClassName::new`。 + ## 默认方法 接口在声明时一般只需要声明其中的方法签名即可,这严格遵循了面向抽象编程的概念。但是严格遵循面向抽象编程所带来的不便就是当接口发生修改时,所有实现了这个接口的类都需要进行修改。对于大型项目来说,这种修改的工作量往往巨大,而且还会造成新版本与旧版本之间的不兼容。为了解决这个问题,Java 8引入了默认方法。