Loading

Java 8 中的特性 - 方法引用

Java 8 Feature - Method References

本文翻译自: Java 8 Method Reference

Method References

在 Java 8 中提供了一个叫做方法引用的新特性。方法引用用于在函数式接口上引用其他方法。它是 Lambda 表达式的一种更简单的形式。当你使用 Lambda 表达式仅仅是为了引用另一个方法时,你可以使用方法引用来替换这些语句。在本教程中,我们将详细的解释方法引用的概念。

方法引用的类型

在 Java 中,方法引用有以下几种类型:

  1. 引用一个静态方法
  2. 引用一个实例方法
  3. 引用一个构造方法

引用静态方法

你可以引用一个类中的静态方法。下面是静态方法引用的语法和示例。

语法

ClassName::staticMethodName

示例1

在接下来的示例中,我们将定义一个函数式接口并引用一个静态方法来实现接口中的 eat() 方法。

interface Eatable {
    void eat();
}

public class MethodReference {
    public static void eatSomething() {
        System.out.println("我在吃饭...");
    }

    public static void main(String[] args) {
        // 引用静态方法
        Eatable eatable = MethodReference::eatSomething;
        // 它等同于以下的 Lambda 表达式
        Eatable eatable1 = () -> MethodReference.eatSomething();
        eatable.eat();
        eatable1.eat();
    }
}

运行结果:

我在吃饭...
我在吃饭...

示例2

在这个示例中,我们使用 Java 中内置的函数式接口 Runnable 来引用一个静态方法。

public class MethodReference2 {
    public static void threadStatus() {
        System.out.println("线程正在运行中...");
    }

    public static void main(String[] args) {
        // 使用 Runnable 中的 run 方法引用静态方法 threadStatus()
        Thread t2 = new Thread(MethodReference2::threadStatus);
        t2.start();
    }
}

运行结果:

线程正在运行中..

示例3

你也可以使用对应的参数列表来引用方法重载中的指定方法。在接下来的示例中,我们定义了三个重载方法来用于方法引用。

import java.util.function.BiFunction;

class Arithmetic {
    // int, int
    public static int add(int a, int b) {
        return a + b;
    }

    // int, float
    public static float add(int a, float b) {
        return a + b;
    }

    // float, float
    public static float add(float a, float b) {
        return a + b;
    }
}

public class MethodReference3 {
    public static void main(String[] args) {
        // 两个 Integer 类型的参数和一个 Integer 类型的返回值
        BiFunction<Integer, Integer, Integer> adder1 = Arithmetic::add;
        // (Integer, Float) 类型的参数列表和一个 Float 类型的返回值
        BiFunction<Integer, Float, Float> adder2 = Arithmetic::add;
        // (Float, Float) 类型的参数列表和一个 Float 类型的返回值
        BiFunction<Float, Float, Float> adder3 = Arithmetic::add;
        int result1 = adder1.apply(10, 20);
        float result2 = adder2.apply(10, 20.0f);
        float result3 = adder3.apply(10.0f, 20.0f);
        System.out.println(result1);
        System.out.println(result2);
        System.out.println(result3);
    }
}

运行结果:

30
30.0
30.0

引用实例方法

像静态方法一样,你也可以引用实例方法。在下面的示例中,我们将展示如何对实例方法进行方法引用。

语法

objectInstance::instanceMethodName

示例

在这个示例中,我们将引用一个对象的非静态的方法。你可以通过类对象或匿名对象来引用方法。


interface Eatable {
    void eat();
}

public class MethodReference4 {
    public void eatSomething() {
        System.out.println("xx正在吃饭...");
    }

    public static void main(String[] args) {
        // 创建一个对象实例
        MethodReference4 methodReference = new MethodReference4();
        // 通过实例名引用非静态方法
        Eatable eatable = methodReference::eatSomething;
        eatable.eat();

        // 引用匿名对象的非静态方法
        Eatable eatable2 = new MethodReference4()::eatSomething;
        eatable2.eat();
    }
}

运行结果:

xx正在吃饭...
xx正在吃饭...

引用构造方法

你可以使用 new 关键字来引用一个构造方法。在这里,我们使用函数式接口来引用一个构造函数。

语法

ClassName::new

示例

interface Messageable {
    Message getMessage(String msg);
}

class Message {
    Message(String msg) {
        System.out.println(msg);
    }
}

public class MethodReference5 {
    public static void main(String[] args) {
        // 引用一个构造函数
        Messageable hello = Message::new;
        hello.getMessage("Hello");
    }
}

总结

通过这些示例我们可以发现,方法引用就是将 Lambda 表达式的参数直接转发到了引用的方法上,并将该方法的返回值作为 Lambda 表达式的返回值进行返回 (构造方法返回了对象本身)。

posted @ 2021-11-27 22:20  xtyuns  阅读(78)  评论(0编辑  收藏  举报