Java 8|方法引用

本文主要介绍 Java 8 新增的方法引用。通过代码范例展示如何将遍历字符串列表的代码用 lambda 表达式简化,进而引出方法引用,说明了使用方法名做参数的正确方式及重点。还总结了方法引用类似 C/C++ 函数指针,支持静态方法、实例方法等类型引用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、方法引用:代码范例

Java 8 中新增加了 方法引用 这个概念。但,什么是方法引用呢 ?

我们先来看一个例子,下面这个范例演示了如何遍历字符串列表并进行一些操作

package com.sjh.test.java8;

import java.util.Arrays;
import java.util.List;

public class LambdaTest1 {
    public static void main(String[] args)
    {
        LambdaTest1 tester = new LambdaTest1();
        tester.run();
    }

    public void run()
    {
        List<String> list = Arrays.asList("Action","Cebci","Back");

        // 输出
        for(String st: list){
            System.out.println(st);
        }

        // 转换为大写
        for(String st: list){
            upperAndPrint(st);
        }
    }

    public static void upperAndPrint(String s)
    {
        System.out.println(s.toUpperCase());
    }
}

执行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.LambdaTest1
Action
Cebci
Back
ACTION
CEBCI
BACK

Process finished with exit code 0

看到那重复的 for(String st: list) 我们可以使用 Java 8 新增的 lambda 表达式和 forEach 改造下让把代码变的更简洁一些。

package com.sjh.test.java8;

import java.util.Arrays;
import java.util.List;

public class LambdaTest2 {
    public static void main(String[] args)
    {
        LambdaTest2 tester = new LambdaTest2();
        tester.run();
    }

    public void run()
    {
        List<String> list = Arrays.asList("Action","Cebci","Back");

        // 输出
        list.forEach(item -> System.out.println(item));


        // 转换为大写
        list.forEach(item -> upperAndPrint(item));
    }

    public static void upperAndPrint(String s)
    {
        System.out.println(s.toUpperCase());
    }
}

运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/... com.sjh.test.java8.LambdaTest2
Action
Cebci
Back
ACTION
CEBCI
BACK

Process finished with exit code 0

果然、使用 Lambda 表达式真的是简洁了不少,但是,还有没有更简单的方式?

比如 item -> System.out.println(item) 这个表达式,其实就是调用 System.out.println() 方法,并把 forEach 迭代列表生成的唯一参数 item 传给它而已

比如 item -> upperAndPrint(item) 这个表达式,也是一样啊,就是把 forEach 生成的唯一参数 item 传给给 upperAndPrint() 方法而已。

那么我们可不可以直接传递方法名给 forEach 呢?

试试下面这样方法吧!

package com.sjh.test.java8;

import java.util.Arrays;
import java.util.List;

public class LambdaTest3 {

    public static void main(String[] args)
    {
        LambdaTest3 tester = new LambdaTest3();
        tester.run();
    }

    public void run()
    {
        List<String> list = Arrays.asList("Action","Cebci","Back");

        // 输出
        list.forEach(System.out.println);

        // 转换为大写
        list.forEach(upperAndPrint);
    }

    public static void upperAndPrint(String s)
    {
        System.out.println(s.toUpperCase());
    }
}

哎呀,好像遇到了点问题:

Information:java: Errors occurred while compiling module 'test'
Information:javac 1.8.0_171 was used to compile java sources
Information:2020-05-29 16:30 - Build completed with 2 errors and 0 warnings in 2 s 35 ms
/Users/sunjiahao/Develop/gitee_project/test/src/com/sjh/test/java8/LambdaTest3.java
Error:(19, 32) java: 找不到符号
  符号: 变量 println
  位置: 类型为java.io.PrintStream的变量 out
Error:(22, 22) java: 找不到符号
  符号: 变量 upperAndPrint
  位置: 类 com.sjh.test.java8.LambdaTest3

这在所有的 Java 版本中都会报错,但是自 Java 8 开始,还真是可以直接传递方法名的,只是我们使用的方式不对而已。

那么我们来调整一下,再看看。

package com.sjh.test.java8;

import java.util.Arrays;
import java.util.List;

public class LambdaTest3 {

    public static void main(String[] args)
    {
        LambdaTest3 tester = new LambdaTest3();
        tester.run();
    }

    public void run()
    {
        List<String> list = Arrays.asList("Action","Cebci","Back");

        // 输出
        list.forEach(System.out::println);

        // 转换为大写
        list.forEach(LambdaTest3::upperAndPrint);
    }

    public static void upperAndPrint(String s)
    {
        System.out.println(s.toUpperCase());
    }
}

运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.LambdaTest3
Action
Cebci
Back
ACTION
CEBCI
BACK

Process finished with exit code 0

OK,现在正确了。

在这个正确的方法中,有两个重点:

1、 方法名和类名之间不是使用点号 ( . ) 而是使用两个冒号 ::
2、 提供的方法名必须包含类名,如果没有引入该类名,则需要使用全限定类名,也就是需要添加包名作为前缀。

这种使用方法名做参数的做法,在 Java 8 中称之为 「 方法引用 」

2、方法引用:总结

方法引用 是 Java 8 新增加的功能。方法引用有点类似于 C / C++ 中的 函数指针 ,通过方法名称指向方法。

Java 8 中的方法引用通过 :: 符号引用方法,而且支持一下类型的方法引用

1、 静态方法
2、 实例方法
3、 使用 new 运算符的构造函数。例如 TreeSet::new

重写上面的范例,演示下如何引用静态方法和实例方法

package com.sjh.test.java8;

import java.util.Arrays;
import java.util.List;

public class LambdaTest4 {

    public static void main(String[] args)
    {
        LambdaTest4 tester = new LambdaTest4();
        tester.run();
    }

    public void run()
    {
        List<String> list = Arrays.asList("Action","Cebci","Back");

        // 输出
        list.forEach(System.out::println);

        // 转换为大写
        list.forEach(LambdaTest4::upperAndPrint);

        // 转换为小写并输出
        list.forEach(this::lowerAndPrint);
    }

    public void lowerAndPrint(String s)
    {
        System.out.println(s.toLowerCase());
    }

    public static void upperAndPrint(String s)
    {
        System.out.println(s.toUpperCase());
    }

}

运行结果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.LambdaTest4
Action
Cebci
Back
ACTION
CEBCI
BACK
action
cebci
back

Process finished with exit code 0
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java小技巧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值