Autoboxing support for the Javatm Programming Language
The need to explicitly convert data of primitive type to reference arises
frequently and is often burdensome. The most typical examples are adding
primitive data to collections. The explicit conversions required are verbose
and induce clutter in the program text.
We propose to modify the JavaTM programming language to allow automatic conversion
of data of primitive type to the corresponding wrapper type.
This proposal eliminates annoying casts and conversions from source code,
and synergizes with the planned addition of generics to the language. The
mechanism for achieving this is the introduction of a new conversion, known
as boxing conversion, which may be used as part of assignment
conversion and method invocation conversion (and possibly elsewhere).
This proposal does not include the dual facility of auto-unboxing. However,
the expert group may choose to contemplate that facility as well, if its
inclusion can be done in a manner that is not overly disruptive to the language
as a whole.
Proposed Changes to Java Language Specification
This section provides draft text for sections of the Java Language Specification
(JLS) that will need to be changed if this proposal is adopted. This text
is tentative, and there may be additional sections of the JLS, not included
here, that may require modification. Nevertheless, these sections provide
a good depature point for the work of the expert group.
// New section, after current 5.1.6
JLS 5.1.7 Boxing Conversion
Boxing conversion converts values of primitive type to corresponding values
of reference type. The
precise rules are as follows:
If i is a value of type boolean, then boxing conversion converts i into
a reference r of class and type
Boolean,
such that r.value() == i.
If i is a value of type byte, then boxing conversion converts i into a reference
r of class and type
Byte, such that r.value() == i.
If i is a value of type char, then boxing conversion converts i into a reference
r of class and type
Character, such that r.value() == i.
If i is a value of type short, then boxing conversion converts i into a
reference r of class and type
Short, such that r.value() == i.
If i is a value of type int, then boxing conversion converts i into a reference
r of class and type
Integer, such that r.value() == i.
If i is a value of type long, then boxing conversion converts i into a reference
r of class and type
Long, such that r.value() == i.
If i is a value of type float, then boxing conversion converts i into a
reference r of class and type
Float, such that r.value() == i.
If i is a value of type double, then boxing conversion converts i into a
reference r of class and type
Double, such that r.value() == i.
If i is a value of any other type, boxing conversion is equivalent to an
identity conversion (5.1.1).
// Comment:
// Note that this formulation disallows any assumptions about the identity
of the boxed values on the
// programmer's part. This would allow (but not require) sharing of some
or all of these references
// (canonical booleans, for example).
// New section, before current 5.1.7
JLS 5.1.8. Unboxing conversion
Unboxing conversion converts values of reference type to corresponding values
of primitive type. The precise rules are as follows:
If r is a reference of type Boolean, then unboxing conversion converts r
into a value v of type boolean,
such that r.value() == v.
If r is a reference of type Byte, then unboxing conversion converts r into
a value v of type byte,
such that r.value() == v.
If r is a reference of type Character, then unboxing conversion converts
r into a value v of type char,
such that r.value() == v.
If r is a reference of type Short, then unboxing conversion converts r into
a value v of type short,
such that r.value() == v.
If r is a reference of type Integer, then unboxing conversion converts r
into a value v of type int,
such that r.value() == v.
If r is a reference of type Long, then unboxing conversion converts r into
a value v of type long,
such that r.value() == v.
If r is a reference of type Float, then unboxing conversion converts r into
a value v of type float,
such that r.value() == v.
If r is a reference of type Double, then unboxing conversion converts r
into a value v of type double,
such that r.value() == v.
// Corrections to 5.1.5 Forbidden conversions (some forbidden conversions
are no longer forbidden).
// Specifically, bullets 1, 2, 5 and 6 are dropped. The resulting section
follows.
// Was 5.1.7; renumbered
5.1.9 Forbidden Conversions
There is no permitted conversion from the null type to any primitive type.
There is no permitted conversion to the null type other than the identity
conversion.
There is no permitted conversion other than string conversion from class
type S to a different class
type T if S is not a subclass of T and T is not a subclass of S.
There is no permitted conversion from class type S to interface type K if
S is final and does not
implement K.
There is no permitted conversion from class type S to any array type if
S is not Object.
There is no permitted conversion other than string conversion from interface
type J to class type T if T
is final and does not implement J.
There is no permitted conversion from interface type J to interface type
K if J and K contain methods
with the same signature but different return types.
There is no permitted conversion from any array type to any class type other
than Object or String.
There is no permitted conversion from any array type to any interface type,
except to the interface
types java.io.Serializable and Cloneable, which are implemented by all arrays.
There is no permitted conversion from array type SC[] to array type TC[]
if there is no permitted
conversion other than a string conversion from SC to TC.
JLS 5.2 Assignment Conversion
Assignment conversion occurs when the value of an expression is assigned
(§15.26) to a variable: the type of the
expression must be converted to the type of the variable. Assignment contexts
allow the use of an identity conversion (§5.1.1)
, a widening primitive conversion (§5.1.2)
, a widening reference conversion (§5.1.4)
, or boxing conversion (§5.1.7).
JLS 5.3 Method Invocation Conversion
Method invocation conversion is applied to each argument value in
a method or constructor invocation (§15.9
, §15.12): the type of the argument expression
must be converted to the type of the corresponding parameter. Method invocation
contexts allow the use of an identity conversion
(§5.1.1), a widening primitive conversion
(§5.1.2), a widening reference conversion
(§5.1.4), or boxing conversion (§5.1.7)
.
// Effects on overloading are discussed in JLS 15.12.2.2, see below
JLS 5.5 Casting Conversion
// Comment: Add references to boxing and unboxing conversion.
// The first few paragraphs of the section are given below
Casting conversion is applied to the operand of a cast operator (15.16):
the type of the operand
expression must be converted to the type explicitly named by the cast operator.
Casting contexts allow the use of an identity conversion (5.1.1), a widening
primitive conversion (5.1.2), a narrowing
primitive conversion (5.1.3), a widening reference conversion (5.1.4), a
narrowing reference
conversion (5.1.5), a boxing conversion (5.1.7) or an unboxing conversion
(5.1.8). Thus casting
conversions are more inclusive than assignment or method invocation conversions:
a cast can do any permitted conversion other than a string conversion.
Value set conversion (5.1.10) is applied after the type conversion.
Some casts can be proven incorrect at compile time; such casts result in
a compile-time error.
A value of a primitive type can be cast to another primitive type by identity
conversion,
if the types are the same, or by a widening primitive conversion or a narrowing
primitive conversion.
A value of a primitive type can be cast to a reference type by boxing conversion
(5.1.7).
A value of a reference type can be cast to a primitive type by unboxing
conversion (5.1.8).
JLS 15.12.2.2 Choose the Most Specific Method
IIf more than one method declaration is both accessible and applicable to
a method invocation, it is necessary to choose one to provide the descriptor
for the run-time method dispatch. The Java programming language uses the
rule that the most specific method is chosen.
The informal intuition is that one method declaration is more specific than
another if any invocation handled by the first method could be passed on
to the other one without a compile-time type error.
The precise definition is as follows. Let m be a name and suppose
that there are two declarations of methods named m, each having
n parameters. Suppose that one declaration appears within a class or
interface T and that the types of the parameters are T1, .
. . , Tn; suppose moreover that the other declaration appears within
a class or interface U and that the types of the parameters are
U1, . . . , Un. Then the method m declared in T
is more specific than the method m declared in U if
and only if both of the following are true:
· T can be converted
to U by method invocation conversion.
· Tj can be converted
to Uj by method invocation conversion, for all j from
1 to n.
A method is said to be maximally specific for a method invocation
if it is applicable and accessible and there is no other applicable and accessible
method that is more specific.
If there is exactly one maximally specific method, then it is in fact
the most specific method; it is necessarily more specific than any other
method that is applicable and accessible. It is then subjected to some further
compile-time checks as described in §15.12.3
.
It is possible that no method is the most specific, because there are two
or more maximally specific methods. In this case:
· If all the maximally specific
methods have the same signature, then:
- ·
If one of the maximally specific methods is not declared
abstract, it is the most specific method.
- · Otherwise, all the
maximally specific methods are necessarily declared
abstract. The most specific method is chosen arbitrarily among the
maximally specific methods. However, the most specific method is considered
to throw a checked exception if and only if that exception is declared in
the throws clauses of each of the maximally specific methods.
· Otherwise, if exactly
one of the maximally specific methods is applicable without use of boxing
conversion, it is the most specific method.
Otherwise, we say that the method invocation is ambiguous, and a
compile-time error occurs.
Copyright 2001-2002 Sun Microsystems, Inc., 901 San Antonio
Road, Palo Alto, California 94303 U.S.A. All rights reserved.