Find JSRs


Ad Banner





staticImport

Importing Static Members in the Javatm Programming Language


Summary


The proposal is to introduce variants of the import statement into the
JavaTM programming language so as to allow importation of static methods
and fields in the manner that classes and interfaces can now be imported.
We propose that a declaration of the form


import static TypeName . Identifier ;


should import into the current compilation unit the name specified by
the Identifier, which must be a static member of the class or interface
named by TypeName. We also propose that a declaration of the form


import static TypeName . * ;


should import into the current compilation unit the names of all
static members of the class or interface named by TypeName.


This proposal requires no changes to the JVM; it involves only the
processing of additional forms of import declarations and an extended
interpretation of simple names at compile time.


Motivation


This proposal addresses two problems in current practice.


(1) Mathematical functions


First is the customary notation for mathematical functions such as
"abs" and "sqrt" and "max". In the Java programming language,
when applying such functions to arguments of type float or double,
it is necessary to write


Math.abs(x) Math.sqrt(x) Math.max(a, b)


where "Math" refers to the class whose full name is "java.lang.Math".
This is undesirably verbose for numerical code compared to what
one can write in languages such as C, Fortran, and Pascal:

abs(x) sqrt(x) max(a, b)

(2) Named constants


It is desirable in many situations to have a set of named constants
such as


public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;


for a traffic light, and it is often deemed undesirably verbose simply
to put them in some utility class TrafficLightand refer to them always
as TrafficLight.RED, TrafficLight.YELLOW, and TrafficLight.GREEN ;
therefore some programmers have taken to defining such constants in
a utility *interface* and then "importing" such constants into a class
by the strategem of declaring the class to "implement" the (otherwise
vacuous) interface. But, inheriting from an interface to get access to
constants in an implementation is a publicly visible operation, and is therefore
subject to all the rules for binary compatibility when modifying the constatnts.
Moreover, it requires all other implementations to inherit the same interface and the same constants,
even though that other implementation may not require them.


This proposal provides a more straightforward mechanism: define the
constants in a utility class, and then import them:


import static TrafficLight.*;


Another advantage: such a declaration is needed only once per
compilation unit rather than once per class.


Note: assuming the accompanying proposal for enumerations is adopted


public class TrafficLight {
...
public enum Color {RED, YELLOW, GREEN}
...
}



Then one has the the choices of:


(a) Writing import mypackage.TrafficLight; and TrafficLight.Color.RED .
(b) Writing import mypackage.TrafficLight.Color; and Color.RED .
(c) Writing import static mypackage.TrafficLight.Color.*; and RED.





Rationale for Choice of Syntax



One might well ask why the keyword static should appear in the
import declaration, for the compiler can easily tell what is to be
imported without the presence of that keyword. There are two reasons:


(a) To distinguish visually the importation of members, such as
methods and fields, from the importation of classes and interfaces
(while it easy for the compiler to tell them apart, it is harder
for people, so a redundant visual cue is useful).


(b) To remind the reader (and the programmer) that only static members
can be so imported. (It does not work to try to refer to an instance
member of an arbitrary class by a simple name, because a simple name
fails to supply necessary information as to which instance of the
class is involved.)



Full Proposal



Here we describe the necessary modifications the the Java Language
Specification (JLS), second edition, for this proposal.


Augment the syntax of the import statement (JLS 7.5) to allow two
more possibilities:


ImportDeclaration:
SingleTypeImportDeclaration
TypeImportOnDemandDeclaration
SingleStaticImportDeclaration
StaticImportOnDemandDeclaration


SingleStaticImportDeclaration:
import static TypeName . Identifier ;


StaticImportOnDemandDeclaration:
import static TypeName . * ;


The TypeName must be the canonical name of a class or interface type;
a compile-time error occurs if the named type does not exist. The named
type must be accessible or a compile-time error occurs. For a
single-static-import declaration, the Identifier must name a static
member of the named type; a compile-time error occurs if there is
no member of that name or if the named member is not accessible.


A single-static-import declaration in compilation unit c of
package p that imports a member named n shadows the declarations of:


* any top level type named n declared in another compilation unit of p.


* any type named n imported by a type-import-on-demand declaration in c.


* any static member named n imported by a static-import-on-demand declaration
in c.


(The rules for a single-type-import declaration in JLS 7.5.1 must have
a similar third bullet added.)


A static-import-on-demand declaration never causes any other declaration
to be shadowed.



(These rules also need to be added to JLS 6.3.1.)


If two single-static-import declarations in the same compilation unit
attempt to import members with the same simple name, then a compile-time
error occurs, unless the two members are the same member of the same type,
in which case the duplicate declaration is ignored.


If a single-static-import declaration imports a member whose simple
name is n, and the compilation unit also contains a single-type-import
declaration that imports a type whose simple name is n, a compile-time
error occurs. (This error occurs even if both declarations refer to
the same type, on the grounds that it is confusing to use two different
mechanisms to redundantly import the same type.)


If a single-static-import declaration imports a member whose simple
name is n, and the compilation unit also declares a top level type
whose simple name is n, a compile-time error occurs.


Option: We could choose to have another set of automatic imports (JLS
7.5.3) by specifying that each compilation unit, besides automatically
importing all public type names in package java.lang, should also
automatically import all public static members of java.lang.Math
thereby making abs sqrt and PI automatically available in all programs.


The rules in JLS 6.5.2 for classification of an AmbiguousName that is
a simple name must be augmented. Between the third and fourth
diamond-bulleted subparagraphs, add:


<> Otherwise, if a static member of that name is declared
in the compilation unit containing the Identifier by a
single-static-import-declaration, then the AmbiguousName
is reclassified as a Typename, a MethodName, or an
Expressionname according to whether that static member
is a class or interface, a method, or a field.



Also, the fifth and sixth diamond-bulleted subparagraphs are replaced by
these three paragraphs:


<> Otherwise, if a type of that name is declared by exactly one
type-import-on-demand declaration of the compilation unit
containing the Identifier, and not by any static-import-on-demand
declaration of the compilation unit containing the Identifier,
then the AmbiguousName is reclassified as a TypeName.


<> Otherwise, if a member of that name is declared by exactly one
static-import-on-demand declaration of the compilation unit
containing the Identifier, and not by any type-import-on-demand
declaration of the compilation unit containing the Identifier,
then the AmbiguousName is reclassified as a TypeName, a MethodName,
or an Expressionname according to whether that static member
is a class or interface, a method, or a field.


<> Otherwise, if a type of that name is declared by more than one
type-import-on-demand declaration of the compilation unit
containing the Identifier, or a member of that name is declared by
more than one static-import-on-demand declaration of that compilation
unit, or a type of that name is declared by a type-import-on-demand
declaration of that compilation unit and a member of that name is
declared
by a static-import-on-demand declaration of that compilation unit,
then a compile-time error occurs.



The rules in JLS 6.5.5.1 for the meaning of a simple type name must
be augmented. The fourth bulleted paragraph is replaced by:


* Otherwise, if a type with that name is declared in the current
compilation unit, either by a single-type-import declaration,
by a single-static-import declaration, or by a declaration
of a class or interface type, then the simple type name denotes
that type.



Also, the sixth and seventh bulleted paragraphs are replaced by these
three paragraphs:


* Otherwise, if a type of that name is declared by exactly one
type-import-on-demand declaration of the compilation unit
containing the Identifier, and not by any static-import-on-demand
declaration of the compilation unit containing the Identifier,
then the simple type name denotes that type.


* Otherwise, if a type of that name is declared by exactly one
static-import-on-demand declaration of the compilation unit
containing the Identifier, and not by any type-import-on-demand
declaration of the compilation unit containing the Identifier,
then the simple type name denotes that type.


* Otherwise, if a type of that name is declared by more than one
type-import-on-demand declaration of the compilation unit
containing the Identifier, or a member of that name is declared by
more than one static-import-on-demand declaration of that compilation
unit, or a type of that name is declared by a type-import-on-demand
declaration of that compilation unit and a member of that name is
declared
by a static-import-on-demand declaration of that compilation unit,
then the name is ambiguous as a type name; a compile-time error occurs.



The rules in JLS 6.5.6.1 for the meaning of a simple expression name must
be augmented. In the second bulleted paragraph, the second and third
diamond-bulleted subparagraphs are replaced by these five subparagraphs:


<> Otherwise, if the class has a member field of that name:


:: If the single member field of that name is declared final ...


:: Otherwise, the expression name denotes a variable ...


<> Otherwise, if a field of that name is declared by exactly one
nonredundant single-static-import declaration of the compilation unit
containing the Identifier:


:: If the static field of that name is declared final or the
field is a member of an interface ...


:: Otherwise, the expression name denotes a variable ...


<> Otherwise, if a field of that name is declared by exactly one
static-import-on-demand declaration of the compilation unit
containing the Identifier:


:: If the static field of that name is declared final or the
field is a member of an interface ...


:: Otherwise, the expression name denotes a variable ...


<> Otherwise, if a field of that name is declared by more than one
static-import-on-demand declaration of the compilation unit
containing the Identifier, then the name is ambiguous as
an expression name; a compile-time error occurs.


<> Otherwise, the name is undefined as an expression name;
a compile-time error occurs.


In the third bulleted paragraph, the second diamond-bulleted
subparagraph is replaced by these five subparagraphs:


<> Otherwise, if the interface has a member field of that name,
the expression name denotes the value of the member field ...


<> Otherwise, if a field of that name is declared by exactly one
nonredundant single-static-import declaration of the compilation unit
containing the Identifier, the expression name denotes the value
of the member field ...


:: If the static field of that name is declared final or the
field is a member of an interface ...


:: Otherwise, the expression name denotes a variable ...


<> Otherwise, if a field of that name is declared by exactly one
static-import-on-demand declaration of the compilation unit
containing the Identifier:


:: If the static field of that name is declared final or the
field is a member of an interface ...


:: Otherwise, the expression name denotes a variable ...


<> Otherwise, if a field of that name is declared by more than one
static-import-on-demand declaration of the compilation unit
containing the Identifier, then the name is ambiguous as
an expression name; a compile-time error occurs.


<> Otherwise, the name is undefined as an expression name;
a compile-time error occurs.


The second sentence of JLS section 6.5.7.1 is replaced by:


The Identifier must name either at least one method of a class or interface
within whose declaration the Identifier appears, or a method imported
by a single-static-import declaration or static-import-on-demand
declaration within the compilation unit within which the Identifier appears.


JLS section 8.4.6.1 is amended by adding this sentence:


An instance method hides all methods of the same signature that
may be imported by single-static-import and static-import-on-demand
declarations.



JLS section 8.4.6.2 is amended by adding this sentence:


A static method also hides all methods of the same signature that
may be imported by single-static-import and static-import-on-demand
declarations.



JLS section 15.12.2.1, the paragraph after the two bulleted paragraphs
has a sentence added to it, so that the whole paragraph reads as follows:


The class or interface determined by the process described in section
15.12.1 is searched for all method declarations applicable to this
method invocation; method definitions inherited from superclasses and
superinterfaces are included in this search. In addition, if the
method invocation has, before the left parenthesis, a MethodName of
the form Identifier, then the search process also examines all methods
that are (a) imported by single-static-import declarations and
static-import-on-demand declarations within the compilation unit
within which the method invocation occurs, and (b) not hidden at the
place where the method invocation appears.



Copyright 2001-2002 Sun Microsystems, Inc., 901 San Antonio Road, Palo Alto, California 94303 U.S.A. All rights reserved.

AltStyle によって変換されたページ (->オリジナル) /