PROPOSAL: Allow the class literal of the surrounding class to be referenced with the 'class' keyword

Peter Runge prunge at velocitynet.com.au
Mon Mar 30 01:08:42 PDT 2009


PROJECT COIN SMALL LANGUAGE CHANGE PROPOSAL FORM v1.0

AUTHOR(S): Peter Runge
prunge at velocitynet dot com dot au

OVERVIEW

FEATURE SUMMARY:

Allow the class literal of the surrounding class to be referenced with
the 'class' keyword.

Sometimes it is useful to be able to reference the class literal of
class containing a body of code.  Right now the name of the surrounding
class with '.class' is used, but it would be beneficial not having to
repeat the class name for this.  This makes it easier to rename the
class later as the name does not need changing in multiple places.

A typical place this feature would provide benefit is create loggers in
logging code.

When expanded, this shortened class literal form is equivalent to its
expanded class literal.

MAJOR ADVANTAGE:

Improves code maintainability - makes it easier to rename classes since
the class name is not repeated in the code.  Also helps defend against
blind copy and pasters.

MAJOR BENEFIT:

Less repeated code - logging code is quite common.

MAJOR DISADVANTAGE:

Requires change to JLS.  Need to weigh up cost of implementing feature
with amount of benefit it would provide.

ALTERNATIVES:

Most IDEs nowadays can automatically rename <classname>.class referenced
in code without too much trouble.

EXAMPLES

Show us the code!

SIMPLE EXAMPLE:

For example, when using logging APIs, a Logger object is often created
as a static variable within a class that is used to generate logging
information in the context of that class.

class MyClass
{
    private static Logger log = Logger.getLogger(MyClass.class);
    ...
}

With the proposal, this can be changed to:

class MyClass
{
    private static Logger log = Logger.getLogger(class);
    ...
}


ADVANCED EXAMPLE: Show advanced usage(s) of the feature.

Inner/nested classes:

class MyClass
{
    private static Logger log = Logger.getLogger(class);

    class MyInnerClass
    {
        Logger innerLog = Logger.getLogger(class);
        //Refers to MyInnerClass.class
        ...
    }
}

Anonymous inner classes:

class MyClass
{
    public myMethod()
    {
        something.invoke(new MyInterface()
        {
            //Refers to the class of the anonymous inner class
            //(not that I've ever needed this, but is there another way
            //short of reflection of accessing this class at
            //the moment apart from getClass()?)
            Logger log = Logger.getLogger(class);

            public void interfaceMethod()
            {
                ...
            }
        });
    }
}

DETAILS

SPECIFICATION:

JLS3 15.8 Primary Expressions: add new syntax for these new class
literals:

PrimaryNoNewArray:
    Literal
    Type.class
    >class<
    void.class
    this
    ClassName.this
    ( Expression )
    ClassInstanceCreationExpression
    FieldAccess
    MethodInvocation
    ArrayAccess

Add description of new class literals to JLS3 15.8.2 (or perhaps add new
section):

...

The class keyword may be used to refer to the class literal for its
enclosing type.  In the case of nested and inner classes, the closest or
'innermost' class is referenced.

The class keyword may be used by itself to refer to its enclosing class,
and behaves equivalently to the usage of a  <enclosing class>.class
literal.
...

COMPILATION:

Potentially these 'class' literals would be resolved and translated into
class literals in their current form using context information.
Therefore no bytecode changes are required.

The exception is anonymous inner classes which have no equivalent class
literal representation in their current form.  It probably wouldn't be a
huge loss if this feature was not allowed to be used in anonymous inner
classes if this was a huge issue, however in bytecode this probably
could be done as easy as any class since all classes anonymous or
otherwise have a binary name which can be loaded in the constant pool.

TESTING:

A test case that uses the new feature can be created.

LIBRARY SUPPORT:

No.

REFLECTIVE APIS:

No reflective API changes are needed.

OTHER CHANGES:

The non-public javac tree API may need a change for this feature
(investigation needed - LiteralTree).

MIGRATION:

All class literals inside a class that refer to that class can be
changed to use the new feature.

COMPATIBILITY

BREAKING CHANGES:

No existing programs should break - 'class' as a keyword is currently
not allowed within an expression.

EXISTING PROGRAMS:

No known issues.

REFERENCES

EXISTING BUGS: None known.

URL FOR PROTOTYPE (optional): None available.






More information about the coin-dev mailing list