Why do some Java library methods delegate to a native method with a nearly-identical signature?

The native version is just an implementation detail.

This pattern separates the public interface of the method from the actual implementation.

I see at least 5 reasons why this is useful:

  • test purpose (you can mock the java method call)
  • alternative implementation: a particular version of the java library may implement that method in pure java form without call to the native implementation (common in swing code).
  • backward compatibility: if in a new version, the method accepts some extra parameters, the original java method signature can be kept and the native implementation adapted.
  • input/output validation: most of the time, before calling the native version, the java code will do some checks on the input parameters and throw exception if needed.
  • isolation: the number of methods that directly uses the native code is limited, allowing more changes in the internal code structure.

You can probably find more advantages.


private native int foo(double bar);

So, eventually this has to call a C++ function for its implementation. In particular, it'll end up calling a function with a name something like:

Java_MyClass_foo

What happens if there are multiple native foo methods with different signatures? Complications. If you do it, Java will add type information into the name of the method it looks for. But it is simply easier if you stick to non-overloaded methods.

public int foo(double bar) {
    return foo0(bar);
}

private native int foo0(double bar);

foo0 has been given a unique name, there should never be a reason to add another foo0. This keeps the implementation of the C++ simple, it never has to deal with mangled names. Even if foo eventually gains an overload, it will call foo1 instead of foo0 and the C++ JNI implementation won't have to deal with the extra complications of overloading.