Механизмы Java при использовании в замыканиях lambdaj
-
06-07-2019 - |
Вопрос
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
Пока Марио