Ограничения анонимных классов Java по сравнению с блоками Objective-C - PullRequest
6 голосов
/ 31 мая 2011

Я только начинаю оборачиваться вокруг функций и замыканий первого порядка после обнаружения блоков в Objective-C. Java - это другой язык, где я слышал о замыканиях (или их отсутствии) и о том, как анонимные классы компенсируют это.

Я определенно вижу преимущества замыканий как блоков в Objective-C, но каковы ограничения анонимных классов Java? В какой степени они «в некоторой степени» восполняют отсутствие истинных замыканий?

Ответы [ 2 ]

10 голосов
/ 31 мая 2011

Java анонимные классы действительно очень многословны.Помимо огромного количества шаблонов, которые вам нужны только для их определения, некоторые из проектных решений Java означают, что многие общие задачи гораздо более многословны, чем в других языках.Например, импорт изменяемых значений в замыкание - трудная задача в Java.

По сути, Java не поддерживает значения вверх;вместо этого они моделируются путем передачи их (по значению) в класс через невидимые параметры в конструктор класса.Поскольку они передаются по значению, их изменение внутри класса не повлияет на копию в методе, который создал класс, поэтому компилятор заставляет вас объявить их окончательно, чтобы не запутаться.Например:

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.Я нахожу, что зачастую проще изменить логику, чтобы не использовать замыкания, просто чтобы я оставил количество используемого кода достаточно маленьким, чтобы быть понятным.

5 голосов
/ 31 мая 2011

Я на самом деле не знаю о версии объектных замыканий C, но я знаю их по Smalltalk и Lua.

Закрытие - это, по сути, функция, которая имеет доступ к локальной переменной некоторой другой функции./ блок (обычно тот, в котором замыкание синтаксически вложено).Таким образом, локальная переменная может жить дольше, чем блок, в котором она определена. Когда у вас есть несколько замыканий для одной и той же переменной, они могут взаимодействовать с помощью этой переменной.

Локальные классы Java (из которых анонимные классы являютсяособый случай) поддерживают ограниченную версию этого: они разрешают доступ к переменной final, то есть к переменной, которая не может изменить свое значение.Это реализуется путем копирования значения этой переменной в объект локального класса в его конструкции.Вы можете эмулировать реальные замыкания, используя изменяемый объект в этой переменной (в простейшем случае - массив из одного элемента).

Кроме того, синтаксис Java для этого довольно уродлив, но он вписывается в остальную частьязык приятен и обеспечивает безопасность статического типа (в отличие от некоторых вариантов с более коротким синтаксисом, которые обсуждаются).

...