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