Defaut methods are not visible if -source 1.7 is set

Dan Smith daniel.smith at oracle.com
Tue Nov 26 16:35:42 PST 2013


I finally had a chance to dig a little deeper into what's actually happening here.  It's a narrower problem than I expected.

javac does a lot of work to ensure that, under -source 7, default methods are "visible" at appropriate times, but don't get in the way:
- You can @Override the method from any subtype
- You never have to implement the method in a subtype
- You can invoke the method as a member of the interface, or a subinterface, or an implementing abstract class

The only exception is that you can't invoke the method as a member of a concrete class:

interface I { default void m() {} }
interface J extends I {}
abstract class A implements I {}
class B implements I {}

// compile with -source 7:
class Test {
  public static void test(I i, J j, A a, B b) {
    i.m(); // ok
    j.m(); // ok
    a.m(); // ok
    b.m(); // error
  }
}

So this looks much less like a design decision and much more like an overlooked corner case.  I've created a bug:
https://bugs.openjdk.java.net/browse/JDK-8029240

I expect this will likely be addressed in an update release of Java 8.

—Dan

On Nov 1, 2013, at 8:59 AM, Stephan Herrmann <stephan.herrmann at berlin.de> wrote:

> In terms of coordinating the behavior of javac and the Eclipse compiler
> I'm happy this issue has been raised here.
> I couldn't see any real conclusion, yet. Did I miss a relevant post?
> How do you think a compiler at -source 1.7 *should* handle default methods?
> 
> Here's another example from an earlier instance of this discussion:
> 
> Compile at -source 1.8:
> 
>  public interface I {
>     default void foo() {}
>  }
> 
> and consuming the .class of the above compile at -source 1.7:
> 
>  public class CI implements I {
>    void test(I i) {
>      this.foo();
>      i.foo();
>    }
>  }
> 
> From two calls to the same method, javac (all versions) flags one:
> 
> CI.java:3: error: cannot find symbol
>      this.foo();
>          ^
>  symbol: method foo()
> 1 error
> 
> Will this be the final behavior of javac?
> 
> For comparison, the Eclipse compiler (beta) currently reports only this:
> 
>        public class CI implements I {
>                     ^^
> The type CI must implement the inherited abstract method I.foo()
> ----------
> 1 problem (1 error)
> 
> Whereas the latest release version reports nothing.
> 
> Stephan
> 
> 
> On 10/29/2013 06:26 PM, Remi Forax wrote:
>> This is from enhanced-metadata-spec-discuss mailing list
>> but I think this issue can interest this audience because it seems
>> that javac doesn't respect the spec we have drafted or the spec has changed without me noticing it.
>> Anyway there is a discrepancy somewhere.
>> 
>> From Joe Darcy:
>> 
>>>> Wouldn't this risk the same issues as when we turned isAnnotationPresent() into a default?
>>>> 
>>>> 
>>> 
>>> No; we don't have the same hazard here as with isAnnotationPresent. The issue we ran into with making isAnnotationPresent a
>>> default method was that isAnnotationPresent was part of the original AnnotatedElement interface defined way back in Java SE 5. In
>>> implementation decision in javac did not expose the existence of default methods to code being compiled under source levels less
>>> than 8. That is a pragmatic choice and usually gives the desired result, but not in this case.
>>> 
>> 
>> So it seems that javac 8 doesn't see default methods if source level is 1.7 (-source 1.7)
>> and as Joe notice this hamper to transform any existing abstract method to a default method.
>> 
>> I'm pretty sure that we have talked about that and said that adding default to a method should be
>> source compatible when we have discussed about Iterator.remove.
>> Otherwise it goes against the intuition that providing a body to an existing abstract method is harmless.
>> 
>> So either javac8 implementation is not correct (BTW, javac7 see default methods)
>> or the spec shoud be changed to say that adding a default implementation is not a compatible change
>> and Iterator.remove should be re-abstracted.
>> 
>> regards,
>> Rémi
>> 
> 



More information about the lambda-spec-experts mailing list