一直在使用JAVA8的函数式编程, 但是对于:: 的操作符在一些情况下的使用还是感觉到一些困惑, 虽然结合上下文不难分析出代码逻辑,但是自己运用::操作符的时候就比较困难了; 今次看了一下官方文档,理解了一下;
文档参考: https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
简单说一下函数式编程,就是在JAVA语言里Method并不是一等公民(他必须被Class, Interface包装) 这导致的结果是一些不需要复用的,简单的,一次性的方法; 我们仍然需要冗长的定义一个内部类; 导致很不简洁,反而影响阅读;
函数式编程的2个重要的操作符号是-> & ::; -> 比较好理解, 这里就说一下::
- :: 的正式名字是方法的引用(method reference), 如果有javascript 编程经验应该很好理解; 过去Java只有对象的引用(Object reference);
- 它仅仅只是一个语法糖, 当编译时,这个方法的引用会被封装成一个类; 它其实是内部类/ -> 更进一步 极简写法(内部类 和 -> 也都是语法糖);
- A::B, 就是引用了Type(Class) A 的 B Method; 它与A.B的写法很像, 但是意义完全不同; 它其实是个callback;
*函数式编程的核心或者说难以理解的地方在于类型推断; 当你传递一个 方法的引用 给程序,程序需要在 恰当的时机 用 恰当的对象 传递 恰当的参数 去call这个方法; 需要理解类型推断的规则才能明白:: 的操作符的含义;
如上图, 最难让人理解的是第三点规则;
翻译一下: 调用 任意 一个 确定类型的实例的方法; 这个规则下 A::B, A是代表一个Type, B不必是静态的方法, 因为执行它的还是实例; 但是到底是哪个实例 调用这个方法呢?Java是如何推断的呢?
如上图例子核心的代码是
Arrays.sort(stringArray, String::compareToIgnoreCase);
我们把他转成->的写法
Arrays.sort(stringArray, (a, b) -> a.compareToIgnoreCase(b));
从这个例子可以看出,第一个参数就是执行这个方法的实例;