JDK-4856541 : add varargs support
  • Type: Enhancement
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 1.4.2
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2003-04-30
  • Updated: 2003-08-01
  • Resolved: 2003-08-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
5.0 tigerFixed
Description
Adding varargs to Java

Abstract

We propose to add variable argument list methods to Java. Existing methods (such as java.text.MessageFormat.format) could be retrofitted to accept variable argument lists without affecting existing clients, while enabling new clients to use an improved invocation syntax. The overload resolution algorithm is modified to support variable argument lists, boxing, and unboxing while retaining backward compatibility both at compile-time and runtime. The implementation resides entirely in the compiler; no support in the VM is necessary.

Motivation

Java has two different kinds of interfaces for composing text output. The first kind consists of chained or sequential method calls such as those from java.io.PrintStream or composition using java.lang.StringBuffer (or the moral equivalent using String concatenation). These methods are convenient and statically typesafe but these techniques do not internationalize well because the order of "snippets" in a message are fixed by the order of calls in the source. The second kind consists of "formatting" classes such as java.text.MessageFormat and related classes that support internationalization. These interfaces are awkward to use and are not statically typesafe, but internationalization is easily supported because the format argument that specifies the order and content of the assembly of the resulting message can be replaced at runtime with one appropriate to the user's native tongue. Think "resource files".

The ideal would be formatting classes that are easy to use, internationalizable, and statically typesafe. These three goals cannot be achieved without nontrivial innovation in the language. Instead we propose a simple language extension that is easy to use and internationalizable, and that supports dynamic (runtime) type safety. No VM modifications are necessary.

Examples

I'll introduce the language feature by way of an example.

package java.text;

class MessageFormat {
    public static String format(String pattern, Object[] arguments...)
    {
        // body omitted
    }
}

This shows one possible way to modify an existing class to take advantage of the new language facility. This existing method has been modified by adding the new ellipsis token "..." to the declaration. The resulting method appears identical from the point of view of the VM, but the compiler allows a new invocation syntax:

import java.text.MessageFormat;
import java.io.PrintStream;
class Test {
    public static void test(PrintStream out, String[] args) {
        // existing invocation syntax
        out.println(MessageFormat.format("Args are {0} {1} {2}",
    	                                 args));
        // new invocation syntax
        out.println(MessageFormat.format("Names are {0} {1} {2}",
                                         "Neal", "Josh", "Mark")); 
    }
}

This may not appear to be much of an advantage, but in real applications that have been internationalized a fair bit of scaffolding typically exists to simplify what would have been required before this extension. Typical clients simulate varargs by declaring a series of overloaded methods, with one, two, three, etc additional arguments. As an example of the scale of the simplifications that will be possible with the new invocation syntax, see the class com.sun.tools.javac.util.Log in the implementation of javac.

Synopsis of the Specification

JLS 8: Formal Parameters

The syntax for method declarations (JLS 8.4) and constructor declarations (JLS 8.8) are modified to support an ellipsis before the closing paren. A method declared with an ellipsis is required to have an array type as its last formal parameter.

JLS 8: Overriding

We would like to require (JLS 8.4.6.1 and 8.4.6.4) that a method that overrides a varargs method is itself declared with an ellipsis. We cannot do that for backward compatibility because retrofitting an existing method with an ellipsis would break its overriders. Instead, in -source 1.5 it would be a warning only; in -source 1.6 (or some later release) it would be enforced as an error.

JLS 13: Binary Compatibility

The binary compatibility chapter (JLS 13) is modified to require the new JVM "Varargs" attribute on those methods that were declared with an ellipsis an on no others. Or perhaps this belongs in the JVM specification.

JLS 15: Overload Resolution

Background: Overload resolution (JLS 15.12) must be modified to support boxing and unboxing conversions. Those changes require using a two-pass overload resolution algorithm. The first pass is for compatibility, and excludes boxing conversions and unboxing conversions. This ensures that existing methods and method invocations are unchanged in their semantic interpretation. Only when the first pass finds no applicable methods does the second pass take place, which considers boxing and unboxing conversions as well.

We further modify this new overload resolution algorithm for varargs. The first pass ignores ellipses in the methods under consideration, even when the methods have been retrofitted for varargs, ensuring backward compatibility. The second pass allows a sequence of arguments to match the trailing array formal parameter of a method declared with an ellipsis when the values can be converted to the element type of the array.

As now, overload resolution selects among the candidates by finding the most specific method. The meta rule is that one method is more specific than another if all arguments that could be accepted by the one could be accepted by the other. These new rules allow the possibility that two (or more) methods are more specific than each other; this is considered an ambiguity and results in a compile-time error.

JLS 15: Runtime evaluation of method invocation

Argument evaluation (JLS 15.12.4.2) must be modified to specify allocating an array and initializing its elements from the relevant arguments if this is necessary to match the invoked method's signature.
Examples

class U {
    static void f(String s, int a, short b) {
	System.out.println("a");
    }
    static void f(String s, int a, int b) {
	System.out.println("b");
    }
    static void f(String s, Integer[] args ...) {
	System.out.println("c");
    }
    static void f(String s, Number[] args ...) {
	System.out.println("d");
    }
    static void f(String s, Object[] args ...) {
	System.out.println("e");
    }
    public static void main(String[] args) {
	f("x", 12, (short)13);	// a
	f("x", 12, 13);		// b
	f("x", 12, 13, 14);	// c
	f("x", 12, 13.5);	// d
	f("x", 12, true);	// e
    }
}


Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: tiger FIXED IN: tiger INTEGRATED IN: tiger tiger-b14
08-07-2004

PUBLIC COMMENTS See jsr201's specification. ###@###.### 2004-01-22
22-01-2004

EVALUATION The specification work for this feature largely overlaps that for unboxing. ###@###.### 2003-04-30
30-04-2003