关闭

在Java中应用函数式编程请小心!

发表于:2015-12-25 09:33

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:santhy    来源:51Testing软件测试网采编

  这并不是要对令人畏惧的函数式编程进行谴责,而是对编程中很容易发生的一些错误进行警醒。
  高阶函数是函数式编程的关键,因此,谈论它们会帮助你在派对上成为关注的焦点。
  如果你正在写 JavaScript ,实际上一直在做的就是高阶函数。例如:
  setTimeout(function() {
  alert('10 Seconds passed');
  }, 10000);
  上面的 setTimeout() 函数就是一个高阶函数。它的参数是一个匿名函数。10秒后,它将会用这个匿名函数作为参数来调用。
  我们可以编写另一个简单的高阶函数,作为结果提供给上面的函数:
  var message = function(text) {
  return function() {
  alert(text);
  }
  };
  setTimeout(message('10 Seconds passed'), 10000);
  如果运行上面的程序,将会执行message() 函数,并返回一个匿名函数,这个匿名函数将会输出传递给 message() 函数的text参数。
  在函数式编程中,上面是很常见的做法。由高阶函数返回的函数被调用时,将会捕捉外部作用域,并且能够在这个作用域上进行操作。
  为什么在 Java 中这种做法很危险?
  出于同样的原因。高阶函数(方法)返回的函数(lambda函数)被调用的时候,会捕捉外部作用域,并且能够在这个作用域上进行操作。
  这里给出一个最简单的例子:
  class Test {
  public static void main(String[] args) {
  Runnable runnable = runnable();
  runnable.run(); // Breakpoint here
  }
  static Runnable runnable() {
  return () -> {
  System.out.println("Hello");
  };
  }
  }
  在上面的逻辑中,如果在 runnable.run() 方法调用处做一个断点,可以看到在堆栈上无害的lambda实例。生成的一个简单类,提供了函数式接口的实现:
  现在,把这个例子转换成普通的企业应用程序(注意注解)。为了方便博客的书写,我们做了很大的简化:
class Test {
public static void main(String[] args) {
Runnable runnable = new EnterpriseBean()
.runnable();
runnable.run(); // Breakpoint here
}
}
@ImportantDeclaration
@NoMoreXML({
@CoolNewValidationStuff("Annotations"),
@CoolNewValidationStuff("Rock")
})
class EnterpriseBean {
Object[] enterpriseStateObject =
new Object[100_000_000];
Runnable runnable() {
return () -> {
System.out.println("Hello");
};
}
}
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号