一、与闭包有关的JAVA语法

JAVA中的闭包,与内部类、匿名内部类和其语法糖 lambda 密切相关
JAVA内部类可以直接访问外部类的私有变量,反之亦然。
定义在函数体内的内部类,也可以访问函数体内的变量,变量名使用final修饰(JDK8开始可以直接访问,不需要final,但建议读者坚持使用final,增强代码可读性)。

二、什么是闭包?

引用了自由变量的函数就是闭包,通过嵌套函数产生闭包,闭包是一个嵌套函数

三、闭包的典型应用

3.1 支持柯里化

柯里化的实质是内部实现类的嵌套。

  1. public class Currying {
  2. //柯里化的目标
  3. public static int add(int x, int y,int z) {
  4. return x + y + z;
  5. }
  6. public interface UnaryAdd { //一元接口
  7. int add(int z);
  8. }
  9. public interface BinaryAdd {
  10. UnaryAdd add(int y);
  11. }
  12. public interface TernaryAdd {
  13. BinaryAdd add(int x);
  14. }
  15. public static void main(String[] a) {
  16. System.out.println(add(2, 3, 4));
  17. TernaryAdd v = x-> y -> z -> x + 2*y - z;//
  18. System.out.println(v.add(2).add(3).add(4));
  19. v = new TernaryAdd(){
  20. @Override public BinaryAdd add(int x){
  21. return new BinaryAdd(){//闭包
  22. @Override public UnaryAdd add(int y){
  23. return new UnaryAdd(){//闭包
  24. @Override public int add(int z){
  25. return x + y + z;
  26. }
  27. };
  28. }
  29. };
  30. }
  31. };
  32. System.out.println(v.add(2).add(3).add(4));
  33. }
  34. }

3.2 支持函数的组合

输出x-y之间符合一定条件的数字。
我们把条件抽象为 Condition函数式接口。

  1. @FunctionalInterface
  2. public interface Condition {
  3. public boolean test(int n);
  4. }
  5. public class Filter {
  6. public static void filter(int x, int y, Condition c) {
  7. for (int i = x; i <= y; i++) {
  8. if (c.test(i)) {
  9. System.out.print(" " + i);
  10. }
  11. }
  12. }
  13. }
  14. public class Client {
  15. public static void main(String[] args) {
  16. Filter.filter(1, 100, n -> n % 3 == 0);
  17. }
  18. }

上面是模板方法的应用。
如果filter需要进行多种条件的测试,我们该怎么做?
更改filter方法形参,接受Condition…可变参数?这改变了模板方法,filter可能已经被使用多次,改变它不是一个好主意。
重新实现一个Condition?可以,但是这给程序员增加了负担,也使得代码变得臃肿。

更好的方法是能够将多个Condition组合起来
本质就是组合的对象

  1. @FunctionalInterface
  2. public interface Condition {
  3. public boolean test(int n);
  4. default Condition and(Condition other){
  5. return n-> this.test(n) && other.test(n);
  6. // return new Condition() {
  7. // @Override
  8. // public boolean test(int n) {
  9. // return Condition.this.test(n) && other.test(n);
  10. // }
  11. // };
  12. }
  13. default Condition or(Condition other){
  14. return n-> this.test(n) || other.test(n);
  15. }
  16. default Condition not(){
  17. return n-> !this.test(n);
  18. }
  19. }
  20. public class Client {
  21. public static void main(String[] args) {
  22. Condition c = n -> {
  23. while (n > 0) {
  24. if (n % 5 == 0) return true;
  25. n = n / 10;
  26. }
  27. return false;
  28. };
  29. Filter.filter(1, 100, c.and(n -> n % 3 == 0));
  30. }
  31. }