Re-specification and re-abstraction

Yuval Shavit yshavit at akiban.com
Thu Dec 22 15:36:16 PST 2011


On Thu, Dec 22, 2011 at 4:42 PM, David Holmes <david.holmes at oracle.com>wrote:

>    To my way of thinking, having the redeclaration be a no-op is what
>>    breaks existing behavior. Let's say I have:
>>
>>         interface Foo {}
>>         interface Bar [extends Foo ] { void myMethod(); }
>>
>>
>>    The previous behavior is that, my BarImpl implements Bar would not
>>    compile if I didn't define myMethod() -- that was the behavior Bar's
>>    author had when he wrote the interface (whether or not the author
>>    cares is another question?). With non-re-abstracted default methods,
>>    that behavior changes.
>>
>
> I still don't understand your example even with Bar extending Foo. Where
> is the default method being added? What "previous behaviour" are you
> referring to?


Initial state, using Java 7:

    public interface Foo {
        void fooMethod();
    }

    public interface Bar extends Foo {
        void barMethod();
    }

    public class BrokenBarImpl implements Bar {
        void fooMethod() {}
        // oops, I forgot to implement barMethod()
    }

The expected behavior is BrokenBarImpl doesn't compile, since it's not
abstract and it hasn't defined barMethod.

Now Foo's author (who may be some third-party vendor) upgrades to Java 8
and makes a change to Foo:

    public interface Foo {
        void fooMethod();
        void barMethod() default { System.out.println("let's go to a bar");
}
    }

The behavior is now that BrokenBarImpl *does* compile, which is a change
from what it was (or could have possibly been) in Java 7.

If I'm Bar's maintainer, my previous expectation is that anyone who
implements Bar will have to write their own definition of barMethod (or get
it from an abstract class). If I want to keep that behavior with Java 8, I
have to preemptively declare barMethod as default none -- otherwise, Foo's
maintainer could unwittingly pull the run from under me by providing a
defaulted Foo.barMethod. (Can you declare a method as default none if none
of its super-interfaces have defaulted that method?)

Put another way, the previous behavior was that if an interface redeclared
a method, that method would require a class to implement it (that happened
to be a no-op requirement, but I'm focusing on the end result). Defaulted
methods change that behavior.  I'm not sure if that's a big problem, I'm
just pointing out that it does change previous behavior.


More information about the lambda-dev mailing list