Bootstrap

一篇文章学会Java8新特性-::方法引用符

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);
}
;