Cross compilation and default methods

Stephan Herrmann stephan.herrmann at berlin.de
Thu Apr 4 09:27:32 PDT 2013


 From the perspective of a compiler developer your answers
are perfectly suitable. IFF you confirm that this behavior is
going to stay, we'll look into making Eclipse behave similarly.

Once we get bug reports about this, however, we'll need another
way of explaining, I'm afraid.

 > It might be a problem with that particular hierarchy; the following
 > works ok:

That's the kind of answer I'm not planning to give to a user :)

cheers,
Stephan

On 04/04/2013 06:10 PM, Maurizio Cimadamore wrote:
> On 04/04/13 16:43, Stephan Herrmann wrote:
>> 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:
>
> It might be a problem with that particular hierarchy; the following
> works ok:
>
> //compiled with JDK 8
> interface I {
> default void m() {}
> }
>
> //compiled with JDK 7
> class E implements I { }
>
>>
>> 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?
> This is a result of the JDK 7 invariant on class well-formedness. If a
> class is well-formed, a class should contain all required concrete
> methods implementing corresponding abstract methods in implemented
> interfaces. This means that javac doesn't even bother looking into
> interfaces when resolving a method call where the receiver is a concrete
> class.
>
> Maurizio
>>
>>
>>> 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