Proposal: Import Aliases for Classes and Static Methods

Phil Varner philvarner at gmail.com
Mon Mar 2 22:11:50 PST 2009


Import Aliases for Classes and Static Methods

http://docs.google.com/Doc?id=dgx74dt7_19dxnspbhj

AUTHOR: Phil Varner

OVERVIEW

FEATURE SUMMARY: The import aliases feature allows a user to provide
an alias underwhich an imported class or statically imported method
must be referred to in the containing source file.   An example of the
use of this feature is "import java.sql.Date as SqlDate;"

MAJOR ADVANTAGE: This feature would allow easier use of multiple
classes which have the same name but different packages to be used in
the same source file.

MAJOR BENEFIT: This will prevent the necessity of fully-qualifiying
all class references when there is a name collision, leading to more
readable code.

MAJOR DISADVANTAGE:  This will introduce an extra level of indirection
when determing the source of a given class or method, introduce a new
keyword 'as', and will require changes to IDE code completion
functionality.

ALTERNATIVES: In some cases, a nested class can be created which
trivially derives a class involved in the name collision.  For a
method, a wrapper method can be created in the source file.

EXAMPLES

SIMPLE EXAMPLE:

Example #1, duplicate class name

Current code:

new java.sql.Date(new java.util.Date());

New code:

import java.sql.Date as SqlDate;
import java.util.Date as UtilDate;

new SqlDate(new UtilDate());

Example #2, statically imported method alias

Current code:

import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName;

public static int mrlacsmn(final int arg1, final String arg2){
    return myReallyLongAndComplicatedStaticMethodName(arg1, arg2);
}

mrlacsmn(1, a);

New code:

import static com.philvarner.some.pkg.myReallyLongAndComplicatedStaticMethodName
as mrlacsmn;

mrlacsmn(1, a);

ADVANCED EXAMPLE:

Example #3

Translation of persistent formats between similar APIs.

In many domains, it is not uncommon to have two different APIs with
classes with the same name.  For example, in a production rules API,
one may have classes "RuleSet" and "Rule".  When attempting to use the
API to translate between these these APIs, it must be decided that one
is fully-qualified and one is not.  This can lead to code like:

com.example.foo.bar.sdk.RuleSet srcRuleSet = ...;
com.example.foo.bar.sdk2.RuleSet dstRuleSet = new
com.example.foo.bar.sdk2.RuleSet();
migrate(srcRuleSet, dstRuleSet);
...

private static void migrate(com.example.foo.bar.sdk.RuleSet srcRuleSet,
                        com.example.foo.bar.sdk2.RuleSet dstRuleSet){
...
}

Note that it is good practice here not to import either class because
it is too easy to accidentally misuse constants and static methods.

With the 'as' syntax, one could instead write the far less verbose and
more readible:

import com.example.foo.bar.sdk.RuleSet as SrcRuleSet;
import com.example.foo.bar.sdk2.RuleSet as DstRuleSet;

...

SrcRuleSet srcRuleSet = ...;
DstRuleSet destRuleSet = new DstRuleSet();
migrate(srcRuleSet, dstRuleSet);

...

private static void migrate(SrcRuleSet srcRuleSet,
                            DstRuleSet dstRuleSet){
...
}

Example #4

Ensuring correct method selection when static importing overloaded methods.

Current code:
import static org.testng.Assert.assertEquals;

public static int aeo(Object arg1, Object arg2){
    assertEquals(arg1, arg2);
}

public static int aec(Collection arg1, Collection arg2){
    assertEquals(arg1, arg2);
}

aeo(obj1, obj2);
aec(list1, list2);

New code:

import static org.testng.Assert.assertEquals(Object, Object) as aeo;
import static org.testng.Assert.assertEquals(Collection, Collection) as aec;

aeo(obj1, obj2);
aec(list1, list2);

Note: it is possible that this sort of method selection is beyond the
scope of a COIN proposal

DETAILS

SPECIFICATION:

Grammar

modification (JLS 3.9):
Keyword:
    as
    ...

modification (JLS 7.5):
ImportDeclaration:
    SingleTypeImportDeclarationWithAlias
    SingleStaticImportDeclarationWithAlias
    ...

addition:
SingleTypeImportDeclarationWithAlias:
    import TypeName as Identifier;

addition:
SingleStaticImportDeclarationWithAlias:
    import static TypeName . Identifier as Identifier;


Note that this would explicitly forbid wildcard imports from being aliased.

There are no known effects on the type system or meaning of
expressions and statements in the Java Programming Language.

COMPILATION: This feature would be a compile-time transform.  It would
only affect the way in which a non-fully qualified class or method
name was resolved to a fully-qualified class or method name.

TESTING: This change would be tested in a manner similar how how the
existing code which resolves the fully-qualified names of classes and
methods is tested.

LIBRARY SUPPORT: No change

REFLECTIVE APIS: No change

OTHER CHANGES: No change

MIGRATION: This change is backwards-compatible with existing code.

COMPATIBILITY

BREAKING CHANGES: No change

EXISTING PROGRAMS: No change

REFERENCES

EXISTING BUGS: None at present

URL FOR PROTOTYPE (optional): None at present



More information about the coin-dev mailing list