浅谈Java 7的闭包与Lambda表达式之优劣
2010-06-15 00:00:00 来源:WEB开发网当然,Java中可以“无中生有”地定义“匿名函数类型”(这点和VB.NET相对更为接近),而不需要像C#一样需要基于特定的“委托类型”,显得更为灵活。
SAM类型支持及闭包
SAM的全称是Single Abstract Method,如果一个类型为SAM类型,则意味着它 1) 是抽象类型(即接口或抽象类),且 2) 只有一个未实现的方法。例如这样一个Java接口便是个SAM类型:
public interface Func<T, R> {
R invoke(T arg);
}
于是我们便可以:
Func<int, int>[] array = new Func<int, int>[10];
for (int i = 0; i < array.length; i++) {
final int temp = i;
array[i] = #(int x)(x + temp);
}
可见,我们使用Lambda表达式创建了Func接口的实例,这点是C#所不具备的。这点十分关键,因为在Java类库中已经有相当多的代码使用了SAM类型。不过我发现,在某些使用SAM的方式下似乎会产生一些“歧义”,例如这段代码:
public class MyClass {
@Override
public int hashCode() {
throw new RuntimeException();
}
public void MyMethod() {
Func<int, int> func = #(int x)(x * hashCode());
int r = func.invoke(5); // throw or not?
}
}
在这里我们覆盖(override)了MyClass的hashCode方法,使它抛出RuntimeException,那么在调用MyMethod中定义的func1对象时会不会抛出异常?答案是否定的,因为在这个Lambda表达式中,隐藏的“this引用”代表了func对象,调用它的hashCode不会抛出RuntimeException。那么,假如我们要调用MyClass的hashCode怎么办?那就稍微有些麻烦了:
更多精彩
赞助商链接