1.::操作符作用
::
称为方法引用符,其作用是:引用某类中的现有方法作为函数式接口中抽象方法的重写,使代码更加简洁。
2.::操作符的用法
::
操作符可以用来引用类的构造方法,对象方法,静态方法。
创建一个Something 类
class Something {
// 构造方法
Something() {}
Something(String something) {
System.out.println(something);
}
// 静态方法
static String startsWith(String s) {
return String.valueOf(s.charAt(0));
}
// 对象方法
String endWith(String s) {
return String.valueOf(s.charAt(s.length()-1));
}
}
创建一个函数式接口,函数式接口通过@FunctionalInterface
注解定义,函数式接口中有且仅有一个抽象方法。
@FunctionalInterface
interface IConvert<F, T> {
T convert(F form);
}
观察接口 IConvert,传参为类型 F,返回类型 T。
访问类Something的静态方法:
IConvert<String, String> convert = Something::startsWith;
String converted = convert.convert("123");
访问类Something的对象方法:
Something something = new Something();
IConvert<String, String> converter = something::endWith;
String converted = converter.convert("Java");
访问类Something的构造方法:
IConvert<String, Something> convert = Something::new;
Something something = convert.convert("constructors");
从以上代码中可以看出,在IConvert
接口中定义了一个抽象方法convert()
,当使用Something::startsWith
相当于实现了IConvert
接口,并重写了convert()
方法,startsWith()
的方法体即为convert()
的方法体。
3.举个实际例子
遍历List集合有很多中方法,使用迭代器,增强for,forEach方法加Lamda表达式,此处我们使用forEach方法加::
的方法。对于Lamda表达式的使用请看这篇文章。
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
list.forEach(System.out::println);
}
以上代码非常简洁,我们可以这样理解:
forEach()
内部需要Consumer
接口的实现类,Consumer
接口就是一个函数式接口,里面有一个抽象方法accept()
,System.out::println
重写了accept()
方法,并实现了Consumer:
public static void main(String[] args) {
List<String> list = Arrays.asList("a", "b", "c");
//println作为accept的重写
Consumer<String> consumer = System.out::println;
list.forEach(consumer);
}