Механизмы Java при использовании в замыканиях lambdaj

StackOverflow https://stackoverflow.com/questions/1615950

Вопрос

Lamdbaj позволяет определять замыкания на языке Java, можно найти различные примеры здесь

Мой вопрос касается базовых механизмов Java, используемых, например, для определения println при закрытии используется следующий код:

Closure println = closure(); 
{ of(System.out).println(var(String.class)); }

Это закрытие может быть впоследствии выполнено с помощью:

println.apply("foobar");

Мне любопытно, какие механизмы в Java позволили бы вызвать of(...).println(...) стать ассоциированным с println сам экземпляр.

Естественно, исходный код lambdaj доступен для чтения, но я надеялся на объяснение чуть более высокого уровня, если у кого-нибудь оно есть.Мои навыки рефлексии доходят до небольшого самоанализа и динамического выполнения методов.

Это было полезно?

Решение

Ну, of , по-видимому, является методом static , который импортируется статически, поэтому его можно вызывать без имени включающего класса. Я ожидаю, что var то же самое. Оба метода должны возвращать некоторый тип, который впоследствии вызывается методами:

public class Printable {
  public void println(Var var);
}

public class Fac {
  public static Printable of(Object o) {
    return new Printable(o);
  }

  public static Var var(Class<?> clazz) {
    return new Var(clazz);
  }

} 

Внезапно:

Fac.of(System.out).println(Fac.var(String.class));

Допустима Java. Используя статический импорт, эй presto:

import static Fac.*;

of(System.out).println(var(String.class));

Фигурные скобки, очевидно, являются допустимыми Java, так как вы можете добавить их в любой метод, чтобы помочь в определении лексической ссылки. Этот стиль разработки API называется свободно и лучше всего демонстрируется библиотека JMock .

Кстати, если это должно вводить замыкания в Java, это довольно нелепо - синтаксис нечитабельно ужасен . Их пример ввода / вывода на самом деле заставил меня смеяться вслух. Попробуйте Scala !

РЕДАКТИРОВАТЬ - два вызова println связаны, я полагаю, потому что первая последовательность вызовов позволяет библиотеке захватывать переменные, которые вы передали в качестве параметров. Они, вероятно, записаны в некоторой структуре ThreadLocal . Когда вы затем вызываете (также предположительно статический) метод println , библиотека использует эти захваченные данные для фактического выполнения поведения на более позднем этапе. Кроме того, в тестовой среде EasyMock используется аналогичный механизм (который использует прокси-серверы Java в фоновом режиме) для сбора ожидаемых значений.

Другие советы

Меня зовут Марио Фаско, и я являюсь главным разработчиком библиотеки lambdaj.

Прежде всего, я хотел бы кое-что прояснить:lambdaj не предназначен для замены какого-либо функционального языка.Как я сказал на прошлой неделе в своем выступлении в Цюрихском конгрессе, если у вас есть шанс использовать Scala, воспользуйтесь им и никогда не оглядывайтесь назад.Здесь вы можете найти резюме моего выступления, где четко указано, что:

http://ctpjava.blogspot.com/2009/10/lambdaj-new-trends-in-java.html

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

Что касается внутреннего механизма lambdaj, да, он использует ThreadLocal для достижения этого результата.Если у вас есть другие вопросы, курьезы или даже лучшие предложения и конструктивная критика по поводу lambdaj, возможно, вам было бы интересно зарегистрироваться в списке рассылки lambdaj здесь:

http://groups.google.com/group/lambdaj

Пока Марио

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top