# Thursday, May 15, 2014
« Java Method Overriding Is FUBAR Part 9 o... | Main | First OpenJDK 8 Based Development Snapsh... »
Default and Static Interface Methods

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).

Thursday, May 15, 2014 12:06:11 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0]