Android N uses new Java 8 language features such as interface default methods and interface static methods, which are features that tools/generator hasn't had to deal with before.
The question: how should they be dealt with?
// JavapublicinterfaceHelloJava8 {
publicstaticfinalintVALUE = 42;
publicvoida ();
publicdefaultvoiddefaultMethod() {
}
publicstaticvoidstaticMethod() {
}
}There are at least three ways to do so:
- Ignore them.
- Expose them.
- Treat them specially.
Ignore them
Interface default methods don't need to be implemented, and static methods aren't implementable. The binding mechanism could thus simply ignore them entirely.
// C#publicinterfaceIHelloJava8{publicvoidA();}publicstaticclassHelloJava8{publicconstintValue=42;}This isn't entirely desirable, because it also means default interface methods can't be called.
IHelloJava8value= ...value.DefaultMethod();// error// No way to invoke HelloJava8.staticMethod()
On the plus side, implementors don't need to worry about them:
publicclassWootJava8:Java.Lang.Object,IHelloJava8{publicvoidA(){}}Expose them
The "simple" version of "expose them" is do the simple thing: static methods are bound in the constant-containing static class, and default methods are bound as normal methods:
// C#publicinterfaceIHelloJava8{publicvoidA();publicvoidDefaultMethod();}publicstaticpartialclassHelloJava8{publicconstintValue=42;publicvoidStaticMethod(){...}}This allows calling both methods:
IHelloJava8value= ...value.DefaultMethod();// worksHelloJava8.StaticMethod();// works
However, this means that C# subclasses need to implement all the default methods:
publicclassWootJava8:Java.Lang.Object,IHelloJava8{publicvoidA(){}publicvoidDefaultMethod(){...}}This might not seem bad in this example, but java.util.Collection contains five default methods (one inherited from Iterable).
This might be fine and acceptable, and we could help this scenario by providing access to the default method implementation:
publicstaticpartialclassHelloJava8{publicvoidInvokeDefaultMethod(IHelloJava8self){/* Non-virtual invocation of HelloJava8.defaultMethod() */}}publicpartialclassWootJava8{publicvoidDefaultMethod(){HelloJava8.InvokeDefaultMethod(this);}}However, such "help" will require documentation and training to know about, complicating use.
Treat them specially
To a large extent, the concern is around C# implementations of the interface. It is seen that requiring that optional methods be implemented will complicate the C# experience. Perhaps we can fix this by splitting out the optional methods?
Then, we can use extension methods to invoke the default methods:
// C#publicinterfaceIHelloJava8{publicvoidA();}publicstaticpartialclassHelloJava8{publicconstintValue=42;publicvoidStaticMethod(){...}publicvoidDefaultMethod(thisIHelloJava8self){// *Virtual* dispatch to invoke self.defaultMethod()}publicinterfaceIDefaultMethods{publicvoidDefaultMethod();}}This allows calling both methods:
IHelloJava8value= ...value.DefaultMethod();// works via extension methodHelloJava8.StaticMethod();// works
It also means that C# types don't need to implement the default methods:
publicpartialclassWootJava8:Java.Lang.Object,IHelloJava8{publicvoidA(){}}...but if the C# type does want to implement them, they can all be implemented by using the IDefaultMethods interface:
publicpartialclassWootJava8:HelloJava8.IDefaultMethods{publicvoidDefaultMethod(){}}
Android N uses new Java 8 language features such as interface default methods and interface static methods, which are features that
tools/generatorhasn't had to deal with before.The question: how should they be dealt with?
There are at least three ways to do so:
Ignore them
Interface default methods don't need to be implemented, and static methods aren't implementable. The binding mechanism could thus simply ignore them entirely.
This isn't entirely desirable, because it also means default interface methods can't be called.
On the plus side, implementors don't need to worry about them:
Expose them
The "simple" version of "expose them" is do the simple thing:
staticmethods are bound in the constant-containingstaticclass, anddefaultmethods are bound as normal methods:This allows calling both methods:
However, this means that C# subclasses need to implement all the default methods:
This might not seem bad in this example, but java.util.Collection contains five default methods (one inherited from
Iterable).This might be fine and acceptable, and we could help this scenario by providing access to the default method implementation:
However, such "help" will require documentation and training to know about, complicating use.
Treat them specially
To a large extent, the concern is around C# implementations of the interface. It is seen that requiring that optional methods be implemented will complicate the C# experience. Perhaps we can fix this by splitting out the optional methods?
Then, we can use extension methods to invoke the default methods:
This allows calling both methods:
It also means that C# types don't need to implement the default methods:
...but if the C# type does want to implement them, they can all be implemented by using the
IDefaultMethodsinterface: