Proposal: Import Aliases for Classes and Static Methods
Joseph D. Darcy
Joe.Darcy at Sun.COM
Wed Mar 4 15:39:00 PST 2009
Greetings.
Static import was surprising complicated in JDK 5. While these aliases
could alleviate some problems, I think they would be easily abused and
even when not being abused render code less readable.
Phil Varner wrote:
> 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.
>
IMO, having alternate names for potentially common classes would be less
readable.
> 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.
>
While grammar changes are part of the picture, the substantive changes
would be to JLSv3 section 6.5 "Determining the Meaning of a Name":
http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.5
-Joe
> 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