浅谈Java 7的闭包与Lambda表达式之优劣
2010-06-15 00:00:00 来源:WEB开发网map(files, #(String f)(new File(f).getCanonicalPath())
但事实上,这么做无法编译通过。为什么?因为getCanonicalPath方法会抛出IOException,我们在调用时必须显式地使用 try...catch进行处理。那么这段代码该怎么写?还真没法写。如果没有Checked Exception的话(如C#),我们还可以这么做(处理第一个抛出的IOException):
try {
map(files, #(String f)(new File(f).getCanonicalPath())
catch (IOException ex) {
...
}
但是,如果我们要写出之前那种“漂亮”的写法,就不能使用Func<T, R>而必须是这样的接口类型:
public interface FuncThrowsIOException<T, R> {
R invoke(T arg) throws IOException;
}
或者是这样的“匿名函数类型”:
#String(String)(throws IOException) // toCanonicalPath = #(String f)(new File(f).getCanonicalPath())
但是,作为Lambda和闭包的常用场景,如map,filter,fold等“函数式”元素,是不可能为某种特定的“异常类型”而设计的——异常类型千变万化,难道这也要用throws Exception来进行“统一处理”吗?Java虽然已经支持对异常类型的“推断”,但Checked Exception还是对Lambda和闭包的适用性造成了很大影响。
因此,我认为Checked Exception是一个“硬伤”。
其他
Java的Lambda和闭包还有一些特性,例如参数的“泛化”:
#boolean(Integer) f = #(Number n)(n.intValue() > 0);
由于Number是Integer的基类,因此我们可以使用Number来构造一个接受Integer参数的匿名函数类型。由于示例较少,我还不清楚这个特性的具体使用场景和意义所在——不过我猜想,在Java中可能允许这样做吧:
#boolean(Number) f = #(Number n)(n.intValue() > 0);
#boolean(Integer) f1 = f; // cast implicitly or explicitly
此外还有一些特性,例如与MethodHandle类型的转化,我就没有特别的看法了。
文章来源:http://blog.zhaojie.me/2010/06/first-version-of-lambda-and-closures-in-java-7.html
更多精彩
赞助商链接