See you at JVMLS
Peter Levart
peter.levart at gmail.com
Thu Aug 20 09:32:30 UTC 2015
On 08/20/2015 10:01 AM, Palo Marton wrote:
>
> If you recreate methods from Bar in Foo$any interface, then any
> change of such method in Bar (addition, signature change, ...)
> will be binary incompatible with separate compilation of Foo even
> though such method is not referenced anywhere in Foo (neither
> overridden nor called).
>
>
> That's one option - create such "shadow" interfaces for superclasses.
> (created by JVM on demand, so no problem with changes in super class
> after compilation).
>
> But I see also one more option: _Enhance JVM so that interface can
> extend (exactly one) class_ (and any number of interfaces). It may
> sound as an "extreme" solution ... but somehow it makes sense to me.
> In current JVM interfaces already extend one class, namely
> java.lang.Object. This is "hardcoded" in JVM - you can e.g. call
> Object methods on interfaces, stack slots with interface are treated
> as containing Object, etc... May be this can be enhanced in a way that
> interface can have also different class as its "superclass". Wild
> idea, but may be in the long term it is the best solution...
>
Interfaces can implicitly extend class j.l.Object only because
j.l.Object has no fields. Interfaces can't have fields. That's the
restriction that allows multiple inheritance of interfaces.
Suppose you would have:
class C {
int x;
}
interface I extends C {
}
class D {
int x;
}
interface J extends D {
}
class E implements I, J {
}
E e = new E();
e.x = 123; // which 'x' ?
// and, more importantly, how could JIT optimize the following methods:
void m1(C c) {
c.x = 123;
}
void m2(D d) {
d.x = 234;
}
// when they could be called as:
m1(new E());
m1(new C());
m2(new E());
m2(new D());
Single inheritance of state is deeply baked into VM design as it allows
the field of a class and all it's subclasses to be always located at the
fixed offset from the beginning of the object.
But, theoretically, each class could have an implicit interface, which
would be it's supertype and would contain all methods that the class
implements and extend all interfaces that the class implements
(including the implicit interface of it's superclass). It could be
constructed on demand and "injected" into the class only in cases when
needed during runtime. Such could be the Bar$any implicit interface of
Bar class (from the example of this thread).
This would still not allow: Foo<any>.class.isAssignableFrom(Bar.class)
to return true, but could solve Remi's concerns about package-private
access to Bar methods via the Foo<any> interface.
But this interface injection seems too heavy weight to support just this
simple aspect. Maybe the Foo<any> interface could just be "marked" with:
interface Foo$any implemented-by-subclasses-of Bar { ...
...meaning that VM would enforce this restriction (Foo$any could only be
implemented by subclasses of Bar) and that Foo$any would implicitly
"inherit" all methods from Bar. This would still not make Foo$any a
subtype of Bar, but inherited methods would be owned by Bar and access
checking would work correctly.
Regards, Peter
More information about the valhalla-dev
mailing list