Java匿名类与Objective-C块相比的局限性

时间:2011-05-31 19:28:18

标签: java objective-c closures block

在Objective-C中发现块后,我才开始围绕一阶函数和闭包。 Java是另一种语言,我听说过关闭(或缺少关闭)以及匿名类如何弥补这一点。

我绝对可以看到闭包作为Objective-C中的块的优点,但匿名Java类的局限性是什么?他们在多大程度上“弥补”缺乏真正的封闭?

2 个答案:

答案 0 :(得分:10)

Java匿名类真的非常罗嗦。除了需要定义它们的大量样板外,Java的一些设计决策意味着许多常见任务比其他语言更冗长。例如,将可变的upvalues导入到闭包中是Java中的一个难题。

基本上,Java不支持upvalues;相反,他们通过将它们(通过值)传递给类,通过类的构造函数的不可见参数进行模拟。因为它们是通过值传递的,所以在类中修改它们不会影响构造类的方法中的副本,因此编译器会让你将它们声明为final,以避免让自己感到困惑。 e.g:

Runnable function()
{
   final int i = 4;
   return new Runnable()
   {
       public void run()
       {
            System.out.println("i="+i);
            // can't modify i here
       }
   }
}

在你的情况下需要修改变量,例如在几乎所有闭包都有用的情况下,你必须作弊:

Runnable function()
{
   final int[] i = new int[1];
   i[0] = 4;
   return new Runnable()
   {
       public void run()
       {
            System.out.println("i="+i[0]);
            i[0] = i[0] + 1;
       }
   }
}

这里,i本身仍然是不可变的,但因为它指向一个可变对象,我可以改变对象的内容。 (当然,在现实生活中我会使用一个类而不是一个数组,因为使用数组真的很难看。这使得它甚至更多罗嗦。)

我认为下一个Java版本将具有语法功能,使所有这些变得更容易,但是现在以封闭为中心的编程在Java中非常麻烦。我发现更改逻辑不使用闭包通常更容易,只是为了让我保持使用的代码量足够小以便可理解。

答案 1 :(得分:5)

我真的不知道闭包的Objective-C版本,但我从Smalltalk和Lua了解它们。

闭包本质上是一个函数,它可以访问某些其他函数/块的局部变量(通常是一个闭包在语法上嵌套的函数)。这样,局部变量可以比它定义的块长寿命。当你对同一个变量有多个闭包时,它们可以使用这个变量进行通信。

Java的本地类(其中匿名类是特殊情况)支持限制版本:它们允许访问final变量,即不能改变其值的变量。这是通过将此变量的值复制到其构造上的本地类对象来实现的。您可以通过在此变量中使用可变对象来模拟真实闭包(在最简单的情况下是单元素数组)。

此外,Java语法非常难看,但它很好地适应了语言的其余部分,并且允许静态类型安全(与所讨论的一些较短语法变体相反)。