- 由来
- 方法引用一:静态方法引用
- 方法引用二:对象实例方法引用
- 方法引用三:类型实例方法引用
- 方法引用四:构造器引用
- 总结
由来
功能接口是只有一个抽象方法的接口,创建一个lambda表达式时,需要有一个对应的功能接口。lambda表达式可以认为是一个功能接口的抽象方法的具体实现。
有一种极端情况,就是一个lambda表达式里面的逻辑非常简单,它只是简单地调用了一个方法。针对这种情况我们就可以省去lambda表达式,改为方法引用,即通过这个方法的名称对这个方法直接进行引用。
方法引用是由lambda表达式演进而来的,是针对lambda表达式的一种特殊情况的简化。
方法引用一:静态方法引用
语法:
Class::staticMethod
该种方法引用取代的lambda表达式形式如下:
(args) -> Cla(args)
静态方法引用取代的是在lambda表达式中通过类名调用一个静态方法的lambda表达式形式。静态方法引用最简单,在方法引用中,不需要传入方法的参数。
如下示例中,Math类的abs方法用于返回入参的绝对的值,我们分别使用了匿名类、lambda表达式和静态方法引用3种方式调用了method01方法,其中Function功能接口的具体实现均为调用Math类的静态方法abs返回参数的绝对值。
类名+静态方法名
方法引用二:对象实例方法引用
语法:
obj::instanceMethod
该种方法引用取代的lambda表达式形式如下:
(args) -> obj.instanceMethod(args)
对象实例方法引用取代的是在lambda表达式中通过对象实例名调用一个实例方法的lambda表达式形式。需要一个对象+方法名的形式来表示。
此种形式的方法引用会额外使用一个对象。如下示例,我们分别使用了匿名类、lambda表达式和对象实例方法引用3种方式调用了method01方法,其中Function功能接口的具体实现均为调用a对象的实例方法increase对参数进行加1并返回。
对象名+实例方法名
方法引用三:类型实例方法引用
语法:
ObjectType::instanceMethod
该种方法引用取代的lambda表达式形式如下:
(obj, args) -> obj.instanceMethod(args)
类型实例方法引用取代的是在lambda表达式中通过第一个参数调用一个实例方法的lambda表达式形式。lambda表达式中的第一个参数后面的参数会作为方法调用的参数使用(如果有的话)。
此种形式的方法引用和对象实例方法引用有点类似,它们调用的都是实例方法,但是类型实例方法引用并不像对象实例方法引用那样直观,它使用类名+实例方法名的形式。
如下示例,Function接口的具体实现均为把int类型的参数转换为float类型的类型并返回。我们分别使用了匿名类、lambda表达式和类型实例方法引用3种方式调用了method01方法。
类名+实例方法名
方法引用四:构造器引用
语法:
ClassName::new
该种方法引用取代的lambda表达式形式如下:
(args) -> new ClassName(args)
当一个lambda表达式中仅仅返回一个新创建的对象时,可以改为类名+new关键字形式的方法引用,如果构造器有多个入参,则需要调整对应的功能接口,使功能接口能够接收同样的参数即可。
如下示例,分别使用匿名类、lambda表达式和方法引用3种方式调用了method01方法。功能接口的实现均为返回一个新的set集合的对象,构造器没有入参。使用的功能接口为java.u
无参构造器引用
如下示例,分别使用匿名类、lambda表达式和方法引用3种方式调用了method01方法。功能接口的实现均为返回一个新的A类的对象,构造器包含一个入参。使用的功能接口为java.u
有参构造器引用
总结
为了替换匿名类,你可以使用lambda表达式;为了替换只有一个方法调用的lambda表达式,你可以使用方法引用。
方法引用并不适用于所有的lambda表达式,它只适用于单方法调用的lambda表达式。所以为了使用方法引用,你首先要有一个只包含一个方法调用的lambda表达式。
lambda表达式和方法引用都是对功能接口的实现,只是方法引用是lambda表达式的升华。