Summary
One of the areas receiving a lot of attention for J7 is simplifying and extending the capabilities of inner classes or adding a new construct the closure. This blog examines the options and compares the different proposals using a typical example, inject.

Advertisement

I have editted this blog to incorporate some improvements suggested by Neal
Gafter - thanks Neal.

Since this is my virgin blog I would like to thank Bill for agreeing to me
blogging and say that I will be blogging mostly about Design Patterns in Java.
Particularly my own pet project a Pattern
Enforcing Compiler™ (PEC™) for Java. However this first blog
is about proposed new features for Java 7 — wow we are talking about
7 and 6 isn't done and dusted yet!

One of the areas receiving a lot of attention for J7 is simplifying and extending
the capabilities of inner classes or adding a new construct the closure. This
blog examines the options and compares the different proposals using a typical
example, inject. Amongst the options on the web are:

Do nothing — Mitts off my favourite language!

Add Closures - which are like inner classes but have read and write access
local variables and return exits from the enclosing method as
well as exiting from the closure (some proposals support break and continue as
well as return). E.g. BGGA
Closures, proposed by Bracha, Gafter, Gosling,
and Ahe.

Add spiffy new syntax that makes anonymous inner classes instance creation
shorter and let inner classes have write access to local variables
(return acts as it currently does for an inner class). E.g. Concise Instance
Creation Expressions (CICE), proposed by Bloch, Lea, and Lee.

Shorter Syntax for Common Operations
in general but with some bias to make inner class syntax, in particular,
shorter and to give inner classes write access to locals (return acts
as it currently does for an inner class). E.g. SSCO Request For Enhancement
6389769, proposed by Yours Truly (note the wild mismatch in standing
between the Authors of the first two proposal and the third :).

In the Appendix to this blog an alternative SSCO proposal to RFE 6389769 is
given and this proposal is used in the example given below. The example below
is straight forward, so you probably don't need to read the details of the
three proposals to understand the example. The details of the proposals are
however worth a read to understand the thought process behind the proposals.

Examples

Taking two examples will illustrate the four different approaches
(my apologies in advance if I don't quite get the syntax exactly correct for
other people's proposals). The examples are taken from some of my code, but
I think they are reasonably typical. I added to my original source code the
throwing of a generic exception (the original didn't throw anything); because
BGGA Closure makes a big deal of exception throwing. The examples are inject (also
called reduce, fold, or accumulate in
some libraries) and forEach (a.k.a. each). inject applies
a function to each element of a list and when all the elements are processed
the result is returned, typically the result is a scalar. Likewise forEach processes each element of a list, but does not return anything. The use of
both inject and
forEach in the examples is the common example usage of summing
a list of integers, whilst I think inject and forEach are typical
methods I am less convinced about the summing of integers example (I have never
actual done this with an inner class and I write scientific software).
However summing of integers is a standard example.

Vote

I obviously prefer SSCO, otherwise I wouldn't be proposing it! I think the
advantages are that it is consistent with current Java (this is also true of
CICE) and that it will not only help with instances of inner classes but will
also reduce verbosity in many places. E.g. it is the shortest code for both
use of the example and declaration of the example. But, which do you prefer?

Appendix - New SSCO Proposal

Acknowledgements: This new SSCO proposal has Rules taken
from or inspired by: RFE 6389769, the discussions in the 6389769 forum, Ruby,
and BGGA Closures.

Rule 0: For a method call allow brackets, (),
to be omitted if there are no arguments and for thelast call in a chain of top
level calls
(method, constructor, or modified new, see Rules 1 and 2 below);
provided that the call isn't ambiguous with respect to a field. Top Level means
the call isn't an argument to another call. Note braces start a new statement
with a new top level; if a new statement is started without braces then this
does not create a new top level (see E.g. 2 for Rule 5 below). The last call
means that for the top level calls only: it is either the only call (and that
call isn't qualified) or it is the call following the last dot. The last call
rule means it must follow the last dot, even if that dot is a qualifier dot
rather than a call dot; so that an integer argument is distinct from a real
argument (see last example Rule 2). E.g.:

Rule 2: Allow new to infer type and use <> to
mean a raw type when a . is used (but not for a space). This rule
considerably shortens generic declarations and also instances of anonymous
inner classes. E.g.:

Rule 3: If an expression ends in } then there
is no need for ; before the brace (like array initializers and
argument lists). This rule helps the readability of instances of anonymous
classes. E.g.:

if ( end ) { break }

Rule 4: Consistently make {} optional for a
single line (not just if etc.). This rule helps the readability
of instances of anonymous classes, see last example Rule 5, and shortens many
simple class and method declarations. E.g.:

Rule 5: Infer return type, method name, arguments and exceptions
if a single method is abstract (works for interfaces or abstract classes) and
it isn't ambiguous. In particular it may be necessary to supply the type of
the method arguments, see example at end. The brackets around the argument
list, even for an empty argument list cannot be omitted; this is needed to
distinguish between a method declaration using the new syntax and an instance
initializer. . This rule helps the readability of instances of anonymous classes.
E.g.:

Rule 7: A throws clause can be empty, which
means the method doesn't throw anything (equivalent to an absent throws clause).
This is useful in conjunction with generics, see rule 8 below. E.g.:

Void call() throws;

Rule 8: Generics are extended to allow varargs (only for
use with Throwables and derivatives). An empty generics varargs
list is allowed and it is equivalent to an absent throws clause (note Rule
5 above). E.g.:

Rule 11: Non-final locals that are referenced by an inner
class are automatically wrapped in a final-tuple instance, like C# 3.0 does.
Note: special treatment, name mangelling temporary required, of non-final arguments
is needed (not shown in example below). E.g.:

RSS Feed

About the Blogger

Dr. Howard Lovatt is a senior scientist with CSIRO, an Australian government owned research organization, and is the creator of the Pattern Enforcing Compiler (PEC) for Java. PEC is an extended Java compiler that allows Software Design Patterns to be declared and hence checked by the compiler. PEC forms the basis of Howard's 2nd PhD, his first concerned the design of Switched Reluctance Motors.