functional programming - Closures

探讨Java中闭包和Lambda表达式的使用,包括变量作用域、有效终态及引用类型处理,展示不同场景下的代码实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

// functional/Closure1.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.function.*;

public class Closure1 {
  int i;

  IntSupplier makeFun(int x) {
    return () -> x + i++;
  }
}
// functional/SharedStorage.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.function.*;

public class SharedStorage {
  public static void main(String[] args) {
    Closure1 c1 = new Closure1(); // [1]
    IntSupplier f1 = c1.makeFun(0);
    IntSupplier f2 = c1.makeFun(0);
    IntSupplier f3 = c1.makeFun(0);
    System.out.println(f1.getAsInt());
    System.out.println(f2.getAsInt());
    System.out.println(f3.getAsInt());
  }
}
/* Output:
0
1
2
*/

 

// functional/Closure2.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.function.*;

public class Closure2 {
  IntSupplier makeFun(int x) { // effective final
    int i = 0; // effective final
    return () -> x + i;
  }
}

change  SharedStorage'[1] Closure1 to Closure2, the output is:

/* Closure2 Output:
0
0
0
*/
// functional/Closure3.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {WillNotCompile}

import java.util.function.*;

public class Closure3 {
  IntSupplier makeFun(int x) {
    int i = 0;
    // Neither x++ nor i++ will work:
    return () -> x++ + i++;
  }
}

show Closure3 compile error, use javac command and the output error:

functional/Closure3.java:13: error: local variables referenced from a lambda expression must be final or effectively final
    return () -> x++ + i++;
                 ^
functional/Closure3.java:13: error: local variables referenced from a lambda expression must be final or effectively final
    return () -> x++ + i++;
                       ^
2 errors

 

// functional/Closure4.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.function.*;

public class Closure4 {
  IntSupplier makeFun(final int x) { // x is final
    final int i = 0; // i is also final
    return () -> x + i;
  }
}
// functional/Closure5.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {WillNotCompile}

import java.util.function.*;

public class Closure5 {
  IntSupplier makeFun(int x) {
    int i = 0;
    i++;
    x++;
    return () -> x + i;
  }
}
/* compile error
functional/Closure5.java:14: error: local variables referenced from a lambda expression must be final or effectively final
    return () -> x + i;
                 ^
functional/Closure5.java:14: error: local variables referenced from a lambda expression must be final or effectively final
    return () -> x + i;
                     ^
2 errors
*/

To fix Closure5.java issue by assigning x and i to final variables before using them in the closure:

// functional/Closure6.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.function.*;

public class Closure6 {
  IntSupplier makeFun(int x) {
    int i = 0;
    i++;
    x++;
    final int iFinal = i;
    final int xFinal = x;
    return () -> xFinal + iFinal;
  }
}
// functional/Closure7.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// {WillNotCompile}

import java.util.function.*;

public class Closure7 {
  IntSupplier makeFun(int x) {
    Integer i = 0; // using references
    i = i + 1;
    return () -> x + i;
  }
}
/* compile error:
functional/Closure7.java:13: error: local variables referenced from a lambda expression must be final or effectively final
    return () -> x + i;
                     ^
1 error
*/

 

// functional/Closure8.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.

import java.util.*;
import java.util.function.*;

public class Closure8 {
  Supplier<List<Integer>> makeFun() {
    final List<Integer> ai = new ArrayList<>(); // remove final also work
    ai.add(1);
    return () -> ai;
  }

  public static void main(String[] args) {
    Closure8 c7 = new Closure8();
    List<Integer> l1 = c7.makeFun().get(), l2 = c7.makeFun().get();
    System.out.println(l1);
    System.out.println(l2);
    l1.add(42);
    l2.add(96);
    System.out.println(l1);
    System.out.println(l2);
  }
}
/* Output:
[1]
[1]
[1, 42]
[1, 96]
*/

This time it works: we modify the contents of the List without producing a compile-time error. When you look at the output from this example, it does seem pretty safe, because each time makeFun() is called, a brand new ArrayList is created and returned—which means it is not shared, so each generated closure has its own separate ArrayList and they can’t interfere with each other.

references:

1. On Java 8 - Bruce Eckel

2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/Closure1.java

3. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/Closure2.java

4. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/Closure3.java

5. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/Closure4.java

6. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/Closure5.java

7. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/Closure6.java

8. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/Closure7.java

9. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/Closure8.java

10. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/functional/SharedStorage.java

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值