Saturday, October 20, 2012

Closures in Java

Have you looked the proposal for Function Types and Closures (Anonymous Function Types) in Java?
You may look upon the proposal at http://blogs.sun.com/roller/resources/ahe/closures.pdf and discuss the proposal athttp://blogs.sun.com/ahe/entry/full_disclosure. You may also check the example using closures given by Neal Gafter on his blog at http://gafter.blogspot.com/2006/08/whats-point-of-closures.html.

This proposal proposes addition of function types in java. Using these function types, we will be able to create a function object inside our java code. The function objects could be passed to methods. If a method accepts an object of an interface type which has only a single method (a.k.a. single method interface eg. ActionListener, Comparator etc.) then we may pass a function type with same signature (and a return type which is same or a subtype of the return type of interface method) and Java would automatically convert a function object to an object of that interface.
The example given in proposal is:



public static void main(String[] args) {
//Created The Function Type
int plus2(int x) { return x+2; }

//Created an object of that function type
int(int) plus2b = plus2;

//invoked that function object
System.out.println(plus2b(2));
}



In my opinion, the closures will help make java code cleaner and Function Types will add a container of logic to Java language. A Class contains data as well as logic; while a function will contain only logic.
Using The FunctionTypes and closures, The OperationHandler Pattern example in my previously posted blog can be rewritten without the need of creating an interface and inner classes as follows:
static void performFileOperation(String filePrefix, File inputFile, void(String filePrefix, File inputFile)throws IOException performOperation) throws IOException {
String fileName = inputFile.getName();
if (inputFile.isDirectory()) {
fileName = fileName + "/";
}
if (inputFile.isDirectory()) {
File[] children = inputFile.listFiles();
int len = children == null ? 0 : children.length;
for (int i = 0; i < len; i++) {
performFileOperation(filePrefix + fileName, children[i], performOperation);
}
}
else {
opHandler.performOperation(filePrefix, inputFile);
}
}

public static void createZipFile(File source, File dest, int compressionLevel) throws IOException {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(dest));
out.setLevel(compressionLevel);
//Creating closure here is not better than creating an anonymous inner class
void(String, File) throws IOException closure = (String filePrefix, File inputFile) {
ZipEntry entry = new ZipEntry(filePrefix + inputFile.getName());
entry.setTime(inputFile.lastModified());
out.putNextEntry(entry);
InputStream in = new FileInputStream(inputFile);
byte[] buffer = new byte[1024];
while (in.available() > 1024) {
in.read(buffer);
out.write(buffer);
}
buffer = new byte[in.available()];
in.read(buffer);
out.write(buffer);
in.close();
out.closeEntry();
};
performFileOperation("", source, closure);
out.close();
}

public static void setLastModifiedDate(File source, java.util.Date lastModifiedDate) {
try {
/*creating closure here eliminates a need to create an anonymous inner class or a concrete class implementing interface FileOperationHandler*/
void(String, File) throws IOException closure = (String filePrefix, File inputFile) {
inputFile.setLastModified(lastModifiedDate.getTime());
};
performFileOperation("", source, closure);
}
catch (IOException ex) {
throw new RuntimeException(ex);
}
}

Please let me know of your opinions by your comments.

No comments:

Post a Comment