Anonymous Classes

An anonymous class is a class without a name. Furthermore, it is not a member of its enclosing class. Instead, an anonymous class is simultaneously declared (as an anonymous extension of a class or as an anonymous implementation of an interface) and instantiated any place where it is legal to specify an expression.

Listing 4-9 demonstrates an anonymous class declaration and instantiation. Listing 4-9. Declaring and instantiating an anonymous class that extends a class abstract class Speaker {

abstract void speak();

public class ACDemo {

public static void main(final String[] args) {

new Speaker()

String msg = (args.length == 1) ? args[0] : "nothing to say";

System.out.println(msg);

Listing 4-9 introduces an abstract class named Speaker and a concrete class named ACDemo. The latter class's main() method declares an anonymous class that extends Speaker and overrides its speak() method. When this method is called, it outputs main()'s first command-line argument or a default message if there are no arguments.

An anonymous class does not have a constructor (because the anonymous class does not have a name). However, its classfile does contain a hidden method that performs instance initialization. This method calls the superclass's noargument constructor (prior to any other initialization), which is the reason for specifying Speaker() after new.

Anonymous class instances should be able to access the surrounding scope's local variables and parameters. However, an instance might outlive the method in which it was conceived (as a result of storing the instance's reference in a field), and try to access local variables and parameters that no longer exist after the method returns.

Because Java cannot allow this illegal access, which would most likely crash the virtual machine, it lets an anonymous class instance only access local variables and parameters that are declared final. Upon encountering a final local variable/parameter name in an anonymous class instance, the compiler does one of two things:

■ If the variable's type is primitive (int or double, for example), the compiler replaces its name with the variable's read-only value.

■ If the variable's type is reference (String, for example), the compiler introduces, into the classfile, a synthetic variable (a manufactured variable) and code that stores the local variable's/parameter's reference in the synthetic variable.

Listing 4-10 demonstrates an alternative anonymous class declaration and instantiation. Listing 4-10. Declaring and instantiating an anonymous class that implements an interface interface Speakable {

public class ACDemo {

public static void main(final String[] args) {

new Speakable() {

String msg = (args.length == 1) ? args[0] : "nothing to say";

public void speak() {

System.out.println(msg);

Listing 4-10 is very similar to Listing 4-9. However, instead of subclassing a Speaker class, this listing's anonymous class implements an interface named Speakable. Apart from the hidden method calling Object() (interfaces have no constructors), Listing 4-10 behaves like Listing 4-9.

Although an anonymous class does not have a constructor, you can provide an instance initializer to handle complex initialization. For example, new Office() {{addEmployee(new Employee("John Doe"));}}; instantiates an anonymous subclass of Office and adds one Employee object to this instance by calling Office's addEmployee() method.

You will often find yourself creating and instantiating anonymous classes for their convenience. For example, suppose you need to return a list of all filenames having the .java suffix. Listing 4-11 shows you how an anonymous class simplifies using the java.io package's File and FilenameFilter classes to achieve this objective.

Listing 4-11. Using an anonymous class instance to return a list of files with .java extensions

String[] list = new File(directory).list(new FilenameFilter() {

public boolean accept(File f, String s) {

return s.endsWith(".java");

NOTE: An instance of an anonymous class is similar to a closure, which is a first-class function (a method not declared in a class) with free variables that are bound in the lexical environment (surrounding scope). A first-class function is a function that can be passed as an argument to or returned from a method. A free variable is a variable referred to in a function that is not a local variable or a parameter. Think of this variable as a placeholder.

Despite their similarity, there are two key differences between these language features. First, anonymous classes are more syntactically verbose than closures. Second, an anonymous class instance does not really close over its surrounding scope, because Java cannot allow the anonymous class instance to access non-final local variables and parameters.

Java version 7 will introduce closures, although the exact syntax and implementation are unknown at the time of writing. However, Baptiste Wicht revealed Oracle's first attempt at implementing closures via his May 29, 2010 blog post "Java 7: Oracle pushes a first version of closures" (http://www.baptiste-wicht.com/2010/05/oracle-pushes-a-first-version-of-closures/).

Was this article helpful?

0 0

Post a comment