Cross compilation and default methods

Stephan Herrmann stephan.herrmann at berlin.de
Thu Apr 4 08:43:34 PDT 2013


Hi Maurizio,

On 04/03/2013 10:43 AM, Maurizio Cimadamore wrote:
> the current status quo is:
>
> 1) javac reads default methods, regardless of the source/target versions
> used to compile
> 2) a class is allowed to implement an interface and _not_ providing
> implementations for the defaults, regardless of source/target
> 3) default method resolution only kicks in when source = 8 (mainly for
> perfomance/compatibility risks)
> 4) well-formedness checks on defaults (i.e. clashes) are only enabled if
> source = 8

Thanks.
Unfortunately, I don't see how this explains the following observation:

compile this at -source 1.8:

	interface I0 {
	  void foo();
	}
	public interface I extends I0 {
	  default void foo() { }
	  default void bar() { }
	}

then compile this at -source 1.7:

	public class C implements I {
	  void test() {
	    foo();
	    bar();
	    I i = this;
	    i.foo();
	    i.bar();
	  }
	}

I get 3 errors:

C.java:1: error: C is not abstract and does not override abstract method 
foo() in I0
public class C implements I {
        ^
C.java:3: error: cannot find symbol
     foo();
     ^
   symbol:   method foo()
   location: class C
C.java:4: error: cannot find symbol
     bar();
     ^
   symbol:   method bar()
   location: class C

Sorry, if I'm being dense.
I can see that I.foo() is not recognized as implementing I0.foo(), OK.
That situation should probably just be avoided by library designers
to avoid confusion.

But why can those methods be invoked via 'i' but not via implicit
'this'? Is this an implementation detail leaking out into observable
behavior? How can this be explained to users?


> I believe this is an area where there's room for improvement; things
> like (3) seems to be counterintuitive given that the compiler knows
> about default methods. What has put me off to go ahead and support
> default method resolution with source < 8 is the fact that the new
> resolution algorithm needs to look at more supertypes than the old one
> (i.e. it needs to look at all supertinterface before being able to give
> up). This leads to subtle problems where you need more dependencies on
> your classpath in order to be able to compile a class, as a seemingly
> unrelated interface that was not needed before will suddenly be
> inspected by javac.

I can see. I don't think users will actually expect full fledged
analysis of default methods in 1.7 mode. Not being blamed about
unimplemented default methods is already good. There has to be a line
beyond which compilation in 1.7 against 1.8 class files tells the
user: sorry, I can't figure this out, please align compiler settings
and versions of class libraries. My main question is: where exactly
will you draw this line? I'd love to see javac and Eclipse drawing
the same line, so can we make this explicit?
 From there, each compiler team can figure out how to explain the
situation to the user.

cheers,
Stephan




More information about the lambda-spec-experts mailing list