Java 8函数式编程2.3 引用值,而不是变量_Java 8函数式编程2.3 引用值,而不是变量试读-查字典图书网
查字典图书网
当前位置: 查字典 > 图书网 > 编程 > Java 8函数式编程 > 2.3 引用值,而不是变量

Java 8函数式编程——2.3 引用值,而不是变量

如果你曾使用过匿名内部类,也许遇到过这样的情况:需要引用它所在方法里的变量。这时,需要将变量声明为final,如例2-5 所示。将变量声明为final,意味着不能为其重复赋值。同时也意味着在使用final 变量时,实际上是在使用赋给该变量的一个特定的值。 例2-5 匿名内部类中使用final 局部变量 final String name = getUserName(); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.out.println("hi " + name); } }); Java 8 虽然放松了这一限制,可以引用非final 变量,但是该变量在既成事实上必须是final。虽然无需将变量声明为final,但在Lambda 表达式中,也无法用作非终态变量。如果坚持用作非终态变量,编译器就会报错。 既成事实上的final 是指只能给该变量赋值一次。换句话说,Lambda 表达式引用的是值,而不是变量。在例2-6 中,name 就是一个既成事实上的final 变量。 例2-6 Lambda 表达式中引用既成事实上的final 变量 String name = getUserName(); button.addActionListener(event -> System.out.println("hi " + name)); final 就像代码中的线路噪声,省去之后代码更易读。当然,有些情况下,显式地使用final代码更易懂。是否使用这种既成事实上的final 变量,完全取决于个人喜好。 如果你试图给该变量多次赋值,然后在Lambda 表达式中引用它,编译器就会报错。比如,例2-7 无法通过编译,并显示出错信息:local variables referenced from a Lambdaexpression must be final or effectively final1。 例2-7 未使用既成事实上的final 变量,导致无法通过编译 String name = getUserName(); name = formatUserName(name); button.addActionListener(event -> System.out.println("hi " + name)); 这种行为也解释了为什么Lambda 表达式也被称为闭包。未赋值的变量与周边环境隔离起来,进而被绑定到一个特定的值。在众说纷纭的计算机编程语言圈子里,Java 是否拥有真正的闭包一直备受争议,因为在Java 中只能引用既成事实上的final 变量。名字虽异,功能相同,就好比把菠萝叫作凤梨,其实都是同一种水果。为了避免无意义的争论,全书将使用“Lambda 表达式”一词。无论名字如何,如前文所述,Lambda 表达式都是静态类型的。因此,接下来就分析一下Lambda 表达式本身的类型:函数接口。 注1: Lambda 表达式中引用的局部变量必须是final 或既成事实上的final 变量。——译者注

展开全文


推荐文章

猜你喜欢

附近的人在看

推荐阅读

拓展阅读

《Java 8函数式编程》其他试读目录

• 2.1 第一个Lambda表达式
• 2.2 如何辨别Lambda表达式
• 2.3 引用值,而不是变量 [当前]
• 2.4 函数接口
• 2.5 类型推断
• 2.6 要点回顾
• 2.7 练习
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  •