Context inside default method body

Brian Goetz brian.goetz at oracle.com
Sat Jul 21 07:48:55 PDT 2012


Despite its obvious disadvantages, C1 does support cases not supported by C2, regardless of issues surrounding protection.  For example:

interface A { void foo() default { … } }
interface B { void foo() default { … } }
interface C extends A, B { void foo() default { A.super.foo(); B.super.foo(); } }

Interface C cannot be written using the "nominal" default form.  


On Jul 21, 2012, at 2:17 AM, Deepak S Patwardhan wrote:

> Hi all,
> 
> So, which way are we leaning ? Allow this.clone() inside default method body
> or not ?
> 
> Consider the two ways of providing defaults:
> 
> C1 (Direct) : public Complex subtract(Complex b) default {  return
> this.add(b.negate());   }
> C2 (ShortCut) : public Complex divide(Complex b) default Complexes.divide;
> 
> Question: is C1 strictly more powerful than C2 ?
> (I previously raised this question in "Virtual extension methods"
> http://mail.openjdk.java.net/pipermail/lambda-dev/2012-July/005151.html).
> 
> I guess the answer now depends on allowing/disallowing invocation of
> Object's protected methods on the caller object. Please correct me if I am
> wrong here.
> 
> *Allow*
> 
> C1 becomes strictly more powerful than C2. It also means we view the
> (Direct) code inside interfaces on the same footing as class code for
> implementing classes. If we indeed go down this path, may I suggest we throw
> away C2 altogether ? We just have to write a little extra code:
> 
> public Complex divide(Complex b) default { Complexes.divide(this, b); }
> 
> *Disallow*
> 
> Then may I suggest we throw away C1 altogether. It will clearly mean that
> defaults are just defaults, and the (shortcut method) code, since it exists
> in a separate class, is not treated at par with the code of the implementing
> classes. This will also keep interfaces free of (Direct, programmer written)
> code.
> 
> Regards,
> Deepak S Patwardhan.
> 
> -----Original Message-----
> From: Dan Smith [mailto:daniel.smith at oracle.com] 
> Sent: 21 July 2012 04:25
> To: Deepak S Patwardhan
> Cc: lambda-dev
> Subject: Re: Context inside default method body
> 
> This is closely tied to the discussion about default methods overriding the
> methods of java.lang.Object.  (See the recent "Defaults for Objects'
> methods" thread).
> 
> As it stands right now, the members of interfaces include certain methods
> that look like public Object methods (see JLS 9.2), but interfaces do not
> actually inherit anything from Object.  You can see this by trying to invoke
> 'clone' on a variable of an interface type, like 'Runnable'.  The error
> message says that member doesn't exist.  (Of course, if it did exist, you'd
> get an error anyway, due to accessibility constraints.  So in 7 it's mostly
> possible to imagine that interfaces _do_ inherit everything from Object,
> unless you're writing code in the java.lang package.)
> 
> Among other things, a problem with inheriting things from 'Object' is that
> it allows interfaces to have non-public members.  That opens a small can of
> worms.
> 
> Anyway, thanks for highlighting the behavior.  It's on the radar, and it's
> useful at least to know that somebody noticed this and cares about it.
> 
> -Dan
> 
> On Jul 20, 2012, at 3:00 AM, Maurizio Cimadamore wrote:
> 
>> Nice catch - the accessibility rules for 'protected' in the compiler 
>> are oblivious to extension methods. I don't see any change in the spec 
>> draft regarding this - but it feels like something that should be 
>> special-cased for the sake of consistency.
>> 
>> Maurizio
>> 
>> On 20/07/12 06:43, Deepak S Patwardhan wrote:
>>> Hi all,
>>> 
>>> The following doesn't compile with the latest build of lambda :
>>> 
>>> public interface Islander {
>>> 
>>>    public void replaceLiver() default {
>>>        try {
>>>            Object myClone = this.clone(); //.. Compile error
>>>            //.. get the replacement from myClone
>>>        } catch (CloneNotSupportedException cnse) {
>>>            throw new UnsupportedOperationException();
>>>        }
>>>    }
>>> }
>>> 
>>> Basically, I cannot access clone(), which is protected in Object, in 
>>> spite of having the *this* reference.
>>> 
>>> I think that's ok and not a big deal since Object has only two 
>>> protected methods, and the other method (finalize) shouldn't be 
>>> invoked by anyone, except the GC.  But, it just feels like a minor 
>>> anomaly that default bodies can do everything that normal (ie Class) 
>>> methods can do, except that they cannot clone their callees. (Don't 
>>> hold limitations of Interfaces against them, like access to instance 
>>> variables)
>>> 
>>> Regards,
>>> Deepak S Patwardhan.
>>> 
>>> 
>> 
>> 
>> 
> 
> 



More information about the lambda-dev mailing list