Java8新特性2——方法引用
注:以下内容基于Java 8,所有代码都已在Java 8环境下测试通过
目录:
1. 方法引用
方法引用提供了一种替代 lambda 表达式的语法,允许以更简洁的方式使用 lambda 表达式,特别是在需要传递方法或者函数作为参数时。
方法引用本质是 lambda 表达式的语法糖,如果一个 lambda 表达式仅仅是调用了另外一个方法,此时可用方法引用替换此 lambda 表达式。
方法引用仅仅是简化了 lambda 表达式的写法,因此方法引用并不能脱离 lambda 表达式单独使用。
2. 使用方法
方法引用使用引用运算符 ::
指向一个方法,有以下几种常见写法:
- 引用构造函数
- 引用静态方法
- 引用成员函数
- 引用某个类型的任意对象的实例方法
3. 引用构造函数
分为构造器引用和数组构造函数引用。
3.1 构造器引用
语法格式:
类名::new
如:
lambda表达式:
() -> new String()
等价于
构造器引用
String::new
使用示例:
public class Main {
public static void main(String[] args) {
MyInterface myClassLambda = (x) -> new MyClass(x);//lambda 表达式
myClassLambda.f(10);
MyInterface myClassFunction = MyClass::new;//方法引用
myClassFunction.f(20);
}
}
class MyClass {
/**
* 参数:整型
* 返回值:MyClass类型
*/
MyClass(int arg) {
System.out.println("有参构造器,参数是" + arg);
}
}
@FunctionalInterface
interface MyInterface {
/**
* 参数:整型
* 返回值:MyClass类型
*/
MyClass f(int a);
}
3.2 数组构造函数引用
语法格式:
数据类型[]::new
如:
lambda表达式:
() -> new int[]
等价于
数组构造函数引用
int[]::new
使用示例:
import java.util.function.IntFunction;
public class Main {
public static void main(String[] args) {
IntFunction<int[]> intArrayLambda = (len) -> new int[len];//lambda 表达式
intArrayLambda.apply(10);
IntFunction<int[]> intFunction = int[]::new;//方法引用
intFunction.apply(10);
}
}
注:IntFunction
是 Java 内置的函数式接口,可用于创建泛型数组。
4.引用静态方法
语法格式:
类名::静态方法名
如:
lambda表达式:
(x) -> Math.sin(x)
等价于
方法引用
Math::sin
使用示例:
public class Main {
public static void main(String[] args) {
MyInterface sinLambda = (x) -> Math.sin(x);//lambda 表达式
MyInterface sinFunction = Math::sin;//方法引用
System.out.println(sinLambda.sin(1.2));
System.out.println(sinFunction.sin(1.2));
}
}
@FunctionalInterface
interface MyInterface {
double sin(double x);
}
5. 引用成员函数
可以分为以下三种:
- 使用对象
- 使用 super 关键字(引用超类)
- 使用 this 关键字
以 this 关键字为例,另外两种类似
语法格式:
this::成员函数名
如:
lambda表达式:
(s) -> this.fun(s)
等价于
方法引用
this::fun
使用示例:
public class Main extends Father {
public static void main(String[] args) {
new Main().test();
}
private void test() {
//lambda 表达式
MyInterface lambda1 = (s) -> new Main().fun(s);
MyInterface lambda2 = (s) -> super.fun(s);
MyInterface lambda3 = (s) -> this.fun(s);
lambda1.f("lambda1");
lambda2.f("lambda2");
lambda3.f("lambda3");
//方法引用
MyInterface function1 = new Main()::fun;
MyInterface function2 = super::fun;
MyInterface function3 = this::fun;
function1.f("function1");
function2.f("function2");
function3.f("function3");
}
void fun(String s) {
System.out.println("调用子类中的 fun:" + s);
}
}
class Father {
void fun(String s) {
System.out.println("调用父类中的 fun:" + s);
}
}
@FunctionalInterface
interface MyInterface {
void f(String s);
}
6. 引用某个类型的任意对象的实例方法
使用示例:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String[] strings = {"abc", "ghi", "def"};
Arrays.sort(strings, String::compareToIgnoreCase);
for (String s : strings) {
System.out.println(s);
}
}
}