Problem with method references

Peter Levart peter.levart at gmail.com
Fri Jan 14 11:19:20 PST 2011


On Friday, January 14, 2011 06:44:15 pm Brian Goetz wrote:
> > If we follow method/constructor invocation syntax as closely as possible,
> > existing Java developers would grasp the syntax more quickly.
> > 
> > The only conceptual addition to method/constructor invocation syntax is prefixing instance 
method / inner class constructor with declaring / enclosing class name:
> >    DeclaringClassName#instanceMethod
> >    
> >    EnclosingClassName#new InnerClass;
> > 
> > ... to construct a function that takes an additional 1st argument being
> > an instance of declaring/enclosing class. These two forms have no
> > analogous counterparts as method/constructor invocations so their syntax
> > does not associate to any known concept.
> 
> The bytecode would disagree :)

I was discussing Java language - not bytecodes (they are implementation detail).

> 
> Inner class constructors show up as constructors that take an outer
> argument.  For a class:
> 
> public class Outer {
>    public class Inner {
>    }
> }
> 
> the inner class bytecode looks like
> 
> public class Outer$Inner extends java.lang.Object{
>    final Outer this$0;
> 
>    public Outer$Inner(Outer);
> }

And although the same or similar bytecodes get generated if you compile the above example as if 
you compile an inner class, from the language perspective these two equivalent Java sources are 
not the same and each requires its own syntax for invocation:

If I compile this:

public class Outer {
    public class Inner {
    }
}

...then the only way to invoke Inner constructor from static context is by using this syntax:

new Outer().new Inner();


but if I compile these two:

public class Outer {
}

public class Outer$Inner {
   final Outer this$0;

   public Outer$Inner(Outer outer) { this$0 = outer; }
}

...then the only way to invoke Outer$Inner constructor is by using this syntax:

new Outer$Inner(new Outer());


The fact that the two examples compile to similar bytecodes is just implementation detail.

> 
> Which means the syntax Inner#new works fine for inner class instances
> too -- if you know about the secret first Outer argument.
> 
> Given that this is at least a CC^2 (corner case of a corner case) or
> even a CC^3, I think we don't want to create new syntax for this.
> (Quiz: what percentage of Java developers have used the outer.new
> Inner() syntax?)

The deal with method/custructor references is among other things creating new syntax. I think 
that this new syntax should follow method/constructor invocation syntax as closely as possible 
and only extend on it to accomodate for desirable new features (as geting a reference to an 
instance method from static context) that don't have their counterparts in direct invocation 
syntax. I think that such syntax extension is better than reusing the same syntax to mean two 
different things depending on the context (static vs. non-static).

Regards, Peter


More information about the lambda-dev mailing list