Закриття в Java 7 [закрито]


105

Що таке закриття? Він повинен бути включений в Java 7. (Закриття обговорювались для включення в Java 7, але врешті-решт не були включені. -Ed) Чи можу будь-хто надати мені якісь надійні посилання, звідки я можу дізнатись інформацію про закриття?

Відповіді:


59

Ось блог Ніла Гафтера, один з піонерів, який представляє закриття на Java. Його допис про закриття з 28 січня 2007 року названий «Визначення закриттів» У його блозі є багато інформації, щоб розпочати роботу, а також відео. Ось чудова розмова Google - Додаткові теми з мов програмування - Закриття для Java з Нілом Гафтером.


2
Чи є у вас більш конкретне посилання, ніж загальний блог?
I82Муч


1
Якщо хтось тупий, як я, і якщо ви б’єте головою об стіну, щоб просто знати, який хак це закриття .... тоді ви йдете .. youtube.com/watch?v=Nj3_DMUXEbE
Піюш Кукадія

Я не можу уявити, як реалізувати закриття мовою, яка спочатку їх не мала. Конечно божевільний
Олександр Міллз

Олександр Міллс просто цікавий .. чому?
Bartzilla

84

Закриття - це блок коду, на який можна посилатися (і передавати його навколо) з доступом до змінних області, що додається.

Починаючи з Java 1.1, анонімний внутрішній клас забезпечив цей інструмент дуже багатослівно. Вони також мають обмеження лише в змозі використовувати final(і визначено призначені) локальні змінні. (Зауважте, навіть немісцеві finalзмінні знаходяться в області застосування, але їх не можна використовувати.)

Java SE 8 призначена для більш стислої версії цього для однометодних інтерфейсів *, що називається "лямбда". Лямбди мають такі самі обмеження, як і анонімні внутрішні класи, хоча деякі деталі змінюються випадковим чином.

Лямбди розробляються в рамках проекту Lambda та JSR 335 .

* Спочатку дизайн був більш гнучким, дозволяючи використовувати єдині абстрактні методи (SAM). На жаль, новий дизайн є менш гнучким, але робить спроби виправдати можливість реалізації в інтерфейсах.


7

За словами Тома Хотіна

Закриття - це блок коду, на який можна посилатися (і передавати його навколо) з доступом до змінних області, що додається.

Зараз я намагаюсь наслідувати приклад закриття JavaScript у Вікіпедії , перекладом на Яву " прямий ", сподіваючись бути корисним:

//ECMAScript
var f, g;
function foo() {
  var x = 0;
  f = function() { return ++x; };
  g = function() { return --x; };
  x = 1;
  print('inside foo, call to f(): ' + f()); // "2"  
}
foo();
print('call to g(): ' + g()); // "1"
print('call to f(): ' + f()); // "2"

Тепер частина Java: Function1 - це інтерфейс "Functor" з arity 1 (один аргумент). Закриття - клас, що реалізує Function1, конкретний Functor, який виконує функцію (int -> int). У методі main () я просто інстанціюю foo як об'єкт закриття, реплікуючи виклики з прикладу JavaScript. Клас IntBox - це просто простий контейнер, він поводиться як масив 1 int:

int a [1] = {0}

interface Function1   {
    public final IntBag value = new IntBag();
    public int apply();
}

class Closure implements Function1 {
   private IntBag x = value;
   Function1 f;
   Function1 g;

   @Override
   public int apply()  {
    // print('inside foo, call to f(): ' + f()); // "2"
    // inside apply, call to f.apply()
       System.out.println("inside foo, call to f.apply(): " + f.apply());
       return 0;
   }

   public Closure() {
       f = new Function1() {
           @Override
           public int apply()  {
               x.add(1);
                return x.get();
           }
       };
       g = new Function1() {
           @Override
           public int apply()  {
               x.add(-1);
               return x.get();
           }
       };
    // x = 1;
       x.set(1);
   }
}
public class ClosureTest {
    public static void main(String[] args) {
        // foo()
        Closure foo = new Closure();
        foo.apply();
        // print('call to g(): ' + g()); // "1"
        System.out.println("call to foo.g.apply(): " + foo.g.apply());
        // print('call to f(): ' + f()); // "2"
        System.out.println("call to foo.f.apply(): " + foo.f.apply());

    }
}

Він друкує:

inside foo, call to f.apply(): 2
call to foo.g.apply(): 1
call to foo.f.apply(): 2 

2
IMO, крім назви, це не має нічого спільного із закриттями
n00b


4

Закриття Java буде частиною J2SE 8 і вийде до кінця 2012 року.

Підтримка закриття Java 8 включає концепцію лямбда-виразів, посилання методу, посилання на конструктор та методи за замовчуванням.

Для отримання додаткової інформації та робочих прикладів для цього, відвідайте: http://amitrp.blogspot.in/2012/08/at-first-sight-with-closures-in-java.html


1
Хм, проте Java 8 не дозволяє змінювати змінну закриття. Гарна стаття.
nawfal


0

Реалізація закриття для Java 5, 6 та 7

http://mseifed.blogspot.se/2012/09/bringing-closures-to-java-5-6-and-7.html

Він містить все, що можна було б попросити ...


Посилання переходить до деякого тексту, що описує його, але код, на який посилається ця сторінка, не існує. Де реалізація?
Джеррі Єремія

@JerryJeremiah Ось вона має іншу назву зараз, також усіх версій, оригінально присутніх, немає (для підтримки не остаточного доступу та іншого через абстрактні класи, його можна знову додати для версій Java 8, на якій платформі ви знаходитесь шукаєте?): bitbucket.org/momomo/opensource/src
mmm

2
Посилання ламаються!
sunleo

я отримав 404 посилання мертве
Олександр Міллз

посилання розірвано (саме тому ми не повинні ставити посилання як відповіді ...)
OhadR
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.