Я лично чувствую, что Java отчаянно нуждается в некоторой форме поддержки замыкания. Тем временем я реализовал основанный на отражении обратный вызов метода общего назначения в Java. Это размещено на моем сайте .
Преимущество этого подхода заключается в его универсальности. Цель состояла в том, чтобы написать API-интерфейс, похожий на обход дерева файловой системы, без необходимости каждый раз определять интерфейс, вместо этого назначая метод в коде, использующий API для выполнения работы.
Например, обход дерева файловой системы для обработки каждого файла:
API дерева каталогов процессов
<code>/**
* Process a directory using callbacks. To interrupt, the callback must throw an (unchecked) exception.
* Subdirectories are processed only if the selector is null or selects the directories, and are done
* after the files in any given directory. When the callback is invoked for a directory, the file
* argument is null;
* <p>
* The callback signature is:
* <pre> void callback(File dir, File ent);
*
* @return Количество обработанных файлов.
* /
static public int processDirectory (File dir, Callback cbk, FileSelector sel) {
return _processDirectory (dir, новый Callback.WithParms (cbk, 2), sel);
}
static private int _processDirectory (File dir, Callback.WithParms cbk, FileSelector sel) {
int cnt = 0;
if (! dir.isDirectory ()) {
if (sel == null || sel.accept (dir)) {cbk.invoke (dir.getParent (), dir); CNT ++; }
}
еще {
cbk.invoke (реж, (Object []) NULL);
File [] lst = (sel == null? Dir.listFiles (): dir.listFiles (sel));
if (lst! = null) {
для (int xa = 0; xa
Использование API-интерфейса Process Directory
С помощью написанного выше метода я могу очень легко обработать дерево каталогов для любой операции; сканирование, подсчет, распечатка и т. д. С небольшим изменением для вызова обратного вызова в каталоге как до, так и после нисходящих операций, таких как удаление файла / дерева, также может быть сделано (требуется дополнительный параметр, чтобы указать природу вызова до / после) ).
static private final Method COUNT =Callback.getMethod(Xxx.class,"callback_count",true,File.class,File.class);
...
IoUtil.processDirectory(root,new Callback(this,COUNT),selector);
...
private void callback_count(File dir, File fil) {
if(fil!=null) { // file is null for processing a directory
fileTotal++;
if(fil.length()>fileSizeLimit) {
throw new Abort("Failed","File size exceeds maximum of "+TextUtil.formatNumber(fileSizeLimit)+" bytes: "+fil);
}
}
progress("Counting",dir,fileTotal);
}