【JDK8 新特性4】方法引用

简介: 在介绍方法引用前,我们要来了解Lambda表达式的冗余场景,虽然Lambda表达式已经帮我们简化的不少代码,但是它还是会有冗余的情况。

1、介绍方法引用

在介绍方法引用前,我们要来了解Lambda表达式的冗余场景,虽然Lambda表达式已经帮我们简化的不少代码,但是它还是会有冗余的情况。

1.1 Lambda的冗余场景

我们这里使用Lambda表达式求一个数组的和。该示例可能会很刻意的为了使用方法应用而做。
19.png
我们Lambda 表达式里中求和方法是调用getSum,这样做就很冗余啊。
接下来我们就来使用方法应用的方式。

1.2 体验方法引用简化Lambda

如果我们在Lambda中所指定的功能,已经有其他方法存在相同方案,那是否还有必要再写重复逻辑?可以直接“引用”过去就好了:
20.png
请注意其中的双冒号 :: 写法,这被称为“方法引用”,是一种新的语法。

1.3 方法引用的格式

  • 符号表示 : ::
  • 符号说明 : 双冒号为方法引用运算符,而它所在的表达式被称为方法引用
  • 应用场景 : 如果Lambda所要实现的方案 , 已经有其他方法存在相同方案,那么则可以使用方法引用。

常见引用方式
方法引用在JDK 8中使用方式相当灵活,有以下几种形式:

  1. instanceName::methodName 对象::方法名
  2. ClassName::staticMethodName 类名::静态方法
  3. ClassName::methodName 类名::普通方法
  4. ClassName::new 类名::new 调用的构造器
  5. TypeName[]::new String[]::new 调用数组的构造器

2、对象名::引用成员方法

这是最常见的一种用法,与上面演示的案例相同。如果一个类中已经存在了一个成员方法,则可以通过对象名引用成员方法,代码为

public class Test {

    public static void main(String[] args) {
        // 实例化时间类
        Date date = new Date();
        //方法应用
        Supplier<Long> getTime = date::getTime;
        System.out.println(getTime.get());
    }
}

这里是为了演示哈,有点刻意了,一般情况下,我们还是可以选择 类.方法名 的方式的。
方法引用的注意事项

  1. 被引用的方法,参数要和接口中抽象方法的参数一样 。
  2. 当接口抽象方法有返回值时,被引用的方法也必须有返回值。

3、类名::引用静态方法

由于在 java.lang.System 类中已经存在了静态方法 currentTimeMillis ,所以当我们需要通过Lambda来调用该方法时,可以使用方法引用 , 写法是:

public class Test {

    public static void main(String[] args) {
        Supplier<Long> supp2 = System::currentTimeMillis;
        System.out.println(supp2.get());
    }
}

4、类名::引用实例方法

Java面向对象中,类名只能调用静态方法,类名引用实例方法是有前提的,实际上是拿第一个参数作为方法的调用者。

public class Test {

    public static void main(String[] args) {
        BiFunction<String, Integer, String> bif = String::substring;
        String hello = bif.apply("hello", 2);
        System.out.println("hello = " + hello);
    }
}

5、类名::new引用构造器

由于构造器的名称与类名完全一样。所以构造器引用使用 类名称::new 的格式表示。
首先是一个简单的 Person 类:

package com.jie.test;

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public Person(String s, Integer integer) {
        System.out.println("有参构造方法");
        System.out.println("s:" + s + "integer:" + integer);
    }

    public Person() {
        System.out.println("调用无参构造");
    }
}

应用

public class Test {

    public static void main(String[] args) {
        Supplier<Person> sup = Person::new;
        System.out.println(sup.get());

        BiFunction<String, Integer, Person> fun2 = Person::new;
        System.out.println(fun2.apply("张三", 18));
    }
}

6、数组::new 引用数组构造器

数组也是 Object 的子类对象,所以同样具有构造器,只是语法稍有不同。

public class Test {

    public static void main(String[] args) {
        Function<Integer, int[]> fun = int[]::new;
        int[] arr = fun.apply(5);
        System.out.println(Arrays.toString(arr));
    }
}

7、总结

1、方法引用是对Lambda表达式符合特定情况下的一种缩写,它使得我们的Lambda表达式更加的精简,也可以理解为Lambda表达式的缩写形式 , 不过要注意的是方法引用只能"引用"已经存在的方法。

2、像今天举的案例,很多情况下是不需要Lambda表达式的,所以大家可以根据自己的选择来。

相关文章
|
1月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
25 1
|
2月前
|
容器
jdk8新特性-详情查看文档
jdk8新特性-详情查看文档
45 3
|
1月前
|
存储 安全 Java
JDK1.8 新的特性
JDK1.8 新的特性
19 0
|
2月前
|
编解码 安全 Java
jdk8新特性-接口和日期处理
jdk8新特性-接口和日期处理
|
3月前
|
API
JDK8的stream有求和方法吗?
【8月更文挑战第20天】JDK8的stream有求和方法吗?
123 3
|
3月前
|
Java API
JDK8到JDK25版本升级的新特性问题之使用Collectors.teeing()来计算一个列表中学生的平均分和总分如何操作
JDK8到JDK25版本升级的新特性问题之使用Collectors.teeing()来计算一个列表中学生的平均分和总分如何操作
|
3月前
|
Java
JDK序列化原理问题之Hessian框架不支持writeObject/readObject方法如何解决
JDK序列化原理问题之Hessian框架不支持writeObject/readObject方法如何解决
|
3月前
|
Oracle Java 关系型数据库
JDK8到JDK29版本升级的新特性问题之未来JDK的升级是否会成为必然趋势,如何理解
JDK8到JDK29版本升级的新特性问题之未来JDK的升级是否会成为必然趋势,如何理解
|
3月前
|
Oracle 安全 Java
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
|
2月前
|
Java 编译器 API
JDK8新特性--lambda表达式
JDK8的Lambda表达式是Java语言的一大进步。它为Java程序提供了更多的编程方式,让代码更加简洁,也让函数式编程的概念在Java中得到了体现。Lambda表达式与Java 8的其他新特性,如Stream API、新的日期时间API一起,极大地提高了Java编程的效率和乐趣。随着时间的流逝,Java开发者对这些特性的理解和应用将会越来越深入,进一步推动Java语言和应用程序的发展。
14 0