Java 8 introduces
default and static interface methods.
Here's an example Java 8 interface:
public interface Foo {
default void m1() {
System.out.println("Hello from default interface method");
}
static void m2() {
System.out.println("Hello from static interface method");
}
}
When this interface is compiled by ikvmc, it produces the approximate
equivalent of the following pseudo C# code:
public interface Foo {
public static class __DefaultMethods {
public static void m1(Foo obj) {
if (obj == null) throw new NullReferenceException();
Foo.<default>m1(obj);
}
}
public static class __Methods {
public static void m2() {
Foo.m2();
}
}
public static void <default>m1(Foo obj) {
System.out.println("Hello from default interface method");
}
public abstract void m1();
public static void m2() {
System.out.println("Hello from static interface method");
}
}
There are a number of things going on here, so let's go over them one by one.
__DefaultMethods
This nested type exists to allow C# code to call the default method
implemenation. So when your C# class implements the Foo interface, it may
implement the m1 method by calling the default method. The reason it is a nested
type is to avoid method name clashes and because the current C# compiler doesn't
allow access to static interface members.
__Methods
This only exists because the current C# compiler doesn't allow access to static
interface members (the new Roslyn C# compiler does). It is similar to the nested
__Fields type that already exists to expose interface fields.
<default>m1
This is a static method that contains the body of the default interface method.
Its name is mangled to avoid conflict with the "real" abstract method.
Internally ikvmc calls this method when a class inherits the default method.
m1
Regular abstract interface method.
m2
Regular static method.
The result of this implementation choice is that it can be quite painful to
implement a Java 8 interface in C#, because you manually have to forward each
default method.
Given the large number of default methods introduced in Java 8 this is going to
make interop quite a bit more inconvenient. A partial workaround for this is to
write more interop code in Java or create a Java base class that implements the
interface so that it can inherit the default methods and then write the
implementation as a C# subclass.
I'm considering changing ikvmc to automatically generate a __BaseClass nested
type inside all public interfaces to at least make it easy to write a class that
implements a single Java interface.
JVM interfaces can also have private methods. The current C# compiler doesn't
like interfaces with non-public members, so the private methods are put into
another nested type by ikvmc (and instance methods are compiled as static
methods).