Syntax for calling super
Brian Goetz
brian.goetz at oracle.com
Mon Aug 27 10:39:22 PDT 2012
So, the simple answer to your question about whether the EG considered
this situation to be "so rare as not to be worth supporting" is a simple
"yes" (see previous e-mail.)
However, your suggestion that it need not be either/or -- that it might
be OK to offer an arcane alternate syntax for the case we wished away --
is worth considering. While the syntax you propose is not beautiful,
the problem it addresses is equally unattractive, and seems worth
exploring.
That said, on the priority list of things to work on, this is pretty
low, and the list is long. So the most likely outcome (if we do any
further exploration on this at all) would be just enough to identify
that we could add this later without making the problem worse.
On 8/27/2012 12:57 PM, Peter Levart wrote:
> The result of the example I gave might actualy be a bug in the compiler (which
> I reported in a separate message).
>
> But what should actualy be the result anyway?
>
> Does K.super.m() in anonymous inner class:
>
> new K() {
> @Override
> public void m() {
> K.super.m();
> }
> }
>
> where K is an interface with default method m() actualy call the K.m() with
> the target being an annonymous instance or does the call refer to the outer
> instance (which is also a class directly implementing K)?
>
> What about if there are several outer classes that all directly implement K
> and you don't want to choose the innermost?
>
> Does EG consider such situations to be so rare that it is not worth supporting
> them?
>
> I can understand that resolving a conflicting default methods inherited from
> two or more interfaces might be way more common, so K.super.m() is the best
> syntax (so far) for selecting the right method, but there should also be a
> (maybe less perfect) way of selecting the outer instance and the super
> interface independently and at the same time.
>
> The syntax I suggested might not be the best for that considering K.super.m()
> is to also select superinterface's default methods, but what about an
> alternative one:
>
> If we accept:
>
> this.super.m()
>
> to be a longer version of:
>
> super.m()
>
> (there are analogues already in Java: this.m() vs. m(); this.x vs. x)
>
> then we can extend and combine this into specifying the instance and the
> superinterface independently:
>
> public class A implements J, K {
>
> public void m() { ... }
>
> class B implements K {
> public void m() {
> super.m(); // is the same as
> this.super.m(); // and in this example the same as more specific
> K.super.m(); // which is the same as
> this.K.super.m(); // but
>
> A.this.K.super.m();
> // can be used to select A outer instance's K superinterface method
> }
> }
> }
>
>
> Regards, Peter
>
> On Monday, August 27, 2012 03:27:23 PM you wrote:
>> On Monday, August 27, 2012 12:41:22 PM Peter Levart wrote:
>>>> K.super.m() already has an existing meaning with inner classes, just as
>>>> K.this.m() does. There's a difference between searching for a type alone
>>>> and searching for an object and then a type. Using the same notation is
>>>> confusing in my view.
>>>
>>> Oh, I wasn't aware of that. That changes things. In particular if there
>>> was
>>> a situation where it could resolve to both (the super method of an outer
>>> instance and the particular super interface's default method). There would
>>> have to be a precendence rule or an unresolvable conflict which
>>> complicates
>>> things further.
>>
>> And here it is (an example):
>>
>> public interface J {
>> void m() default {
>> System.out.println("J: " + this);
>> }
>> }
>>
>> public interface K {
>> void m() default {
>> System.out.println("K: " + this);
>> }
>> }
>>
>> public class C implements J, K {
>> @Override
>> public void m() {
>> new K() {
>> @Override
>> public void m() {
>> K.super.m();
>> }
>> }.m();
>>
>> K.super.m();
>> }
>>
>> public static void main(String[] args) {
>> new C().m();
>> }
>> }
>>
>>
>> ... this example prints two different lines in the form:
>>
>> K: C$1 at 65f9c5c8
>> K: C at 712801c5
>>
>> Because K.super.m() is the same syntax used for two different things, I
>> cannot call the same super method in inner class as I can directly in the
>> body of C::k()...
>>
>>
>> Regards, Peter
More information about the lambda-dev
mailing list