Cross compilation and default methods
maurizio.cimadamore at oracle.com
Wed Apr 3 01:43:58 PDT 2013
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
4) well-formedness checks on defaults (i.e. clashes) are only enabled if
source = 8
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.
On 01/04/13 20:42, Stephan Herrmann wrote:
> At JavaOne in SF I discussed with some people how a new
> compiler should handle default methods found in class files
> when compiling with -source 1.7 -target 1.7.
> Obviously, this occurs, e.g., if no proper 1.7 JRE is
> given on the bootclasspath.
> Given that Eclipse users typically expect that our compiler
> behaves the same as javac even in unspecified matters,
> I'd like to request confirmation how javac handles this now
> and in the future.
> While the answer I got in SF indicated that this is a quite
> unsupported situation to begin with, recent experiments
> indicate, that javac does indeed employ some sophistication
> to reduce the number of unexpected errors.
> Could you please confirm that the following behavior is
> correctly analyzed:
> Given we're compiling in 1.7 mode and encounter a default
> method in a class file, this information is kept during
> compilation so that default methods can be specially handled
> in these ways:
> - clients of the interface see the default method just as
> a regular interface method, invocation is possible
> as normal.
> - implementors of the interface do not see/inherit the
> default method at all, with twofold consequences:
> - implementors of the interface need not implement
> its default methods
> - the default method is not visible via the implementing
> class, not even in self calls.
> - interfaces extending the given interface, do inherit
> the default method, invocation via the sub-interface
> is possible
> - implementors of the sub-interface still don't see
> the default method.
> BTW, in earlier JRE versions (around b47) this caused funny
> errors against implementors of Collection, which saw the
> abstract method addAll() from Fillable but did not see the
> non-abstract override from Collection, thus flagging a
> undesirable error saying that addAll() must be implemented.
> Is my above description of the behavior correct?
> Is there more we should know in this area?
> Is this behavior meant to stay, or should we expect any
> changes before Java 8 GA?
More information about the lambda-spec-observers