Find JSRs
Submit this Search


Ad Banner
 
 
 
 

JSRs: Java Specification Requests
JSR 65: Concise Object-Array Literals

This JSR has been Withdrawn
Reason: Withdrawn at the request of the Spec Lead with the agreement of the Expert Group. The community requirements targeted in this JSR are now being addressed as part of autoboxing in JSR 201.

Update to the Java Specification Request (JSR)

The change of Specification Lead has resulted in the following change to the original JSR.

Section 1. Identification

Submitting Participant: Sun Microsystems, Inc.

Name of Contact Person: Gilad Bracha

E-Mail Address: gilad.bracha@eng.sun.com

Telephone Number: 408-863-3116

Fax Number: 408-343-1797


Original Java Specification Request (JSR)

Identification | Request | Contributions

Section 1. Identification

Submitting Participant: Sun Microsystems, Inc.

Name of Contact Person: Mark Reinhold

E-Mail Address: mr@eng.sun.com

Telephone Number: 408-343-1830

Fax Number: 408-343-1797

this information has been updated since the original.)

Section 2: Request

2.1 Please describe the proposed Specification:

The Java programming language provides no convenient way to pass a variable number of arguments to a method, similar to the varargs feature of C or the &rest keyword of Common Lisp. This feature is extremely useful in GUI APIs, in constructing and manipulating collections, and in APIs for formatted output.

One of the goals of JSR-51, New I/O APIs for the Java Platform, for example, is to provide a simple API for formatted textual output similar to the well-known printf procedure of the standard C library. The central method of such an API accepts a format string followed by some arguments, where the exact number of arguments required depends upon the content of the format string. Ideally we'd like to be able to write something like this:

    Formatter f = new Formatter(System.out);
    f.fmt("%d bytes in %d seconds (%.2f KB/s)\n",
          nbytes, seconds,
          ((double)(nbytes / 1024) / (double)seconds));
The Java programming language, as presently defined, does not allow this. The proposed specification will support this syntax, or a syntax very much like it, with a small, transparent, tightly focused language change.

2.2 What is the target Java platform? (i.e., desktop, server, personal, embedded, card, etc.)

All platforms that make use of the full Java programming language: Personal, embedded, desktop, and server.

2.3 What need of the Java community will be addressed by the proposed specification?

The proposed specification will increase developer productivity by providing direct language support for a very common programming idiom. It will make Java that much more attractive an alternative to other competing platforms.

2.4 Why isn't this need met by existing specifications?

There are three ways to support varying numbers of arguments without changing the language. No one is completely satisfactory.

Massive overloading Declare many different methods, all with the same name but different signatures, reflecting all the possible combinations of argument counts and types. In the formatting API, for example, declare

    public class Formatter {
        public void fmt(String fmt, int arg1) { ... }
        public void fmt(String fmt, String arg1) { ... }
        public void fmt(String fmt, int arg1, int arg2) { ... }
        public void fmt(String fmt, int arg1, String arg2) { ... }
        public void fmt(String fmt, String arg1, int arg2) { ... }
        public void fmt(String fmt, String arg1, String arg2) { ... }
        public void fmt(String fmt, int arg1, int arg2, int arg3) ...
        ...
    }
Each method would simply package up its arguments and pass control to a common internal formatting method.

This technique can work if there are only a few possible types and if there is a fairly small lower bound on the total number of arguments. Otherwise the number of methods required tends to explode combinatorically. For the formatting API there are nine argument types and no limit to the number of arguments. Even a fixed limit, say six, would require 531,441 distinct methods.

Object arrays Declare a single formatting method that takes a format string and an array of objects, requiring the invoking code to package its arguments into an object array itself:

    public class Formatter {
        ...
        public void fmt(String format, Object[] args) { ... }
        ...
    }

    f.fmt("%d bytes in %d seconds (%.2f KB/s)\n",
          new Object[] { new Integer(nbytes),
                         new Integer(seconds),
                         new Double((double)(nbytes / 1024)
                                    / (double)seconds)});
This technique, which is used in many existing Java platform APIs, works but is very tedious to use. In this example it has bloated two lines of fairly readable code into six lines that intermix the code for constructing the object array with the code for computing the argument values.

Chained methods Declare a single formatting method that takes a format string and returns an auxiliary argument collector object that collects and processes the arguments:

    public class Formatter {
        ...
        public ArgumentCollector fmt(String format) { ... }
        ...
    }

    public interface ArgumentCollector {
        public ArgumentCollector a(boolean arg);
        public ArgumentCollector a(byte arg);
        public ArgumentCollector a(short arg);
        public ArgumentCollector a(char arg)
        public ArgumentCollector a(int arg);
        public ArgumentCollector a(long arg);
        public ArgumentCollector a(float arg);
        public ArgumentCollector a(double arg);
        public ArgumentCollector a(Object arg);
        public void end();
    }

A class implementing the ArgumentCollector interface has one method for each possible argument type as well as an end method to identify the end of the argument list. The argument methods return the ArgumentCollector object itself, allowing arguments to be passed with a fairly compact syntax:

    f.fmt("%d bytes in %d seconds (%.2f KB/s)\n")
     .a(nbytes).a(seconds)
     .a((double)(nbytes / 1024) / (double)seconds)
     .end();
The chained-method technique supports much more concise use cases than object arrays. It is, unfortunately, complicated by the need for an auxiliary interface to handle argument collection. It is also more error-prone: If the user forgets to invoke the end method then no output will appear. This is a fairly difficult type of bug to find and fix.

No one of the above alternatives is completely satisfactory. The first is impractical in general, the second is extremely verbose, and the third is rather odd in appearance and somewhat error prone. These choices suggest that a very small, tightly focussed change to the Java programming language might be a better solution.

2.5 Please give a short description of the underlying technology or technologies:

The best approach to solving the stated problem appears to be to add a facility for concise, automatically-boxing object-array literals. In short, the syntax of expressions would be extended to allow a list of expressions within curly braces; for example,

    int i;
    double x;
    String s;

    ... { i, x, s } ...
This would be expanded by the compiler into an object-array literal that "boxes" any values of primitive type using the appropriate wrapper classes from the java.lang package:
    ... new Object[] { new Integer(i), new Double(x), s } ...
Thus the above formatting example could be written very concisely as:
    f.fmt("%d bytes in %d seconds (%.2f KB/s)\n",
          { nbytes, seconds,
            ((double)(nbytes / 1024) / (double)seconds) });
This proposal has the following advantages:
  • The use cases are nearly as compact as the ideal syntax shown above. Only two more tokens, namely the curly braces, are required.

  • The declaration of methods that accept varying numbers of arguments is no different than in the object-array case. This makes it easy to define varargs-style methods that exploit this feature.

  • This new syntax can be used with existing APIs that accept object arrays without having to change those APIs. The Swing API has numerous constructors and methods that take object arrays (e.g., javax.swing.table.DefaultTableModel); these are prime candidates for the new syntax. Similar cases can be found in the collections framework (e.g., java.util.Arrays.asList).

  • This is a very narrow language change, being essentially an abbreviation of the more general array-initializer syntax for an extremely common case. Extending the bytecode compiler to support the new syntax is straightforward and low risk.

  • This proposal does a better job of preserving linguistic transparency than the ideal syntax. The ideal syntax boxes primitive values and creates an object array without providing any visual cue that such work is being done. The proposed syntax uses the curly-brace delimiters to indicate that something special is going on.
The only apparent disadvantage to this proposal is that a minor language change is required.

2.6 Is there a proposed package name for the API Specification? (i.e., javapi.something, org.something, etc.)

Not applicable: This is a language change only.

2.7 Does the proposed specification have any dependencies on specific operating systems, CPUs, or I/O devices that you know of?

No.

2.8 Are there any security issues that cannot be addressed by the current security model?

No.

2.9 Are there any internationalization or localization issues?

No.

2.10 Are there any existing specifications that might be rendered obsolete, deprecated, or in need of revision as a result of this work?

The Java Language Specification will require minor revision as a result of this work. Existing specifications that make use of object-array arguments could, at the option of their maintainers, be revised to suggest that the new concise object-array literal notation be employed.



Section 3: Contributions

3.1 Please list any existing documents, specifications, or implementations that describe the technology. Please include links to the documents if they are publicly available.

Sun has developed a preliminary set of changes to the Java Language Specification that describe the syntax and semantics of concise object-array literals. This document is not publicly available.

3.2 Explanation of how these items might be used as a starting point for the work.

The draft JLS changes will serve as a starting point for the work of the Expert Group.