Java 8 方法引用 (Method Reference)快速介绍与示例

本文介绍了Java 8中新增的MethodReference特性,如何将已有方法作为Lambda表达式使用,通过Usr类实例展示静态方法和实例方法引用,并探讨了其演化过程。讲解了静态方法引用、构造方法引用和实例方法引用的区别,以及在实际排序操作中的应用。

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

Method Reference 是什么?

Method Reference 是Java 8 才开始提供的新特性, 翻译过来是方法引用。
其定义就是: 把已经定义好的名字和方法, 当做Lambda 表达式来使用。
官方给出的解释是: They are compact, easy-to-read lambda expressions for methods that already have a name.

Method Reference 的常用语法是 : className::methodName

Method Reference 使用示例

有如下用户类:

public class Usr {

	private String name;

	public Usr(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public static int compareByName(Usr u1,Usr u2) {
		return u1.name.compareTo(u2.name);
	}

}

该类有一个name 的属性 和一个静态方法 compareByName(), 该方法用于根据name比较两个Usr对象。
对以上Usr类型的数组进行排序可以使用如下写法:

	@Test
	public void methodRef() {
		Usr[] usrArray = new Usr[] { new Usr("张飞"), new Usr("关羽"), new Usr("刘备") };
		Arrays.sort(usrArray, Usr::compareByName);
		Assert.assertTrue(usrArray[0].getName().equals("关羽"));
	}

Method Reference 的演化过程

Method Reference 其实对应的是Lambda 表达式, 其是如何一步步演变成 className::methodName的呢? 同样以上面的例子来演示。

不使用Lambda 表达式的写法
	@Test
	public void withoutMethodRef2() {
		Usr[] usrArray = new Usr[] { new Usr("张飞"), new Usr("关羽"), new Usr("刘备") };
		Arrays.sort(usrArray, new Comparator<Usr>() {
			@Override
			public int compare(Usr o1, Usr o2) {
				return Usr.compareByName(o1, o2);
			}
		});
		Assert.assertTrue(usrArray[0].getName().equals("关羽"));
	}

这里使用匿名内部类的方式创建了一个实现Comparator接口的类, 并且实现了其中的compare() 方法。

演进: Lambda 表达式

如果不使用方法引用, 使用Lambda 的写法如下:

		@Test
	public void lambda2() {
		Usr[] usrArray = new Usr[] { new Usr("张飞"), new Usr("关羽"), new Usr("刘备") };
		Arrays.sort(usrArray, (Comparator<Usr>) (Usr u1,Usr u2) -> { return Usr.compareByName(u1, u2);});
		Assert.assertTrue(usrArray[0].getName().equals("关羽"));
	}
  • (Usr u1,Usr u2) 参数, 定义了两个Usr 类型的参数
  • { return u1.getName().compareTo(u2.getName());} 方法体返回一个整型的数字
继续演进

因为Usr.compareByName(u1, u2) 已经定义了输入和输出, 所以左边的参数可以省略。于是
(Usr u1,Usr u2) -> { return Usr.compareByName(u1, u2); => Usr::compareByName

总结: 所谓的方法引用, 就是可以将方法看成是一个对象, 引用这个对象, 参数不需要写, 使用 :: , 这个可以也结合js 中的方法对象来理解。

方法引用的类型

以上演示的是静态方法引用, 其实包括静态方法, 可以引用的方法包括:

  • ClassName::staticMethodName 静态方法引用
  • ClassName::new 构造方法引用
  • instanceReference::instanceMethodName 实例上的实例方法引用
  • ClassName::instanceMethodName 类型上的实例方法

备注

此处对象数组的比较仅用于演示, 一般状况很少在实体类中定义静态比较方法, 常见的比较方式如下:

	@Test
	public void withoutMethodRef() {
		Usr[] usrArray = new Usr[] { new Usr("张飞"), new Usr("关羽"), new Usr("刘备") };
		Arrays.sort(usrArray, new Comparator<Usr>() {
			@Override
			public int compare(Usr o1, Usr o2) {
				return o1.getName().compareTo(o2.getName());
			}
		});
		Assert.assertTrue(usrArray[0].getName().equals("关羽"));
	}
	@Test
	public void lambda() {
		Usr[] usrArray = new Usr[] { new Usr("张飞"), new Usr("关羽"), new Usr("刘备") };
		Arrays.sort(usrArray, (Comparator<Usr>) (Usr u1,Usr u2) -> { return u1.getName().compareTo(u2.getName());});
		Assert.assertTrue(usrArray[0].getName().equals("关羽"));
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

oscar999

送以玫瑰,手留余香

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

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

打赏作者

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

抵扣说明:

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

余额充值