Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

java

native

After delving into the source code for the JRE library, I noticed a strangely common code structure, like this:

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

What is the purpose of this code pattern, and why is it used instead of simply exposing the underlying native method as the public one?

like image 528
RamenChef Avatar asked Aug 15 '16 01:08

RamenChef


People also ask

Why you might want to define a native methods in Java?

Native methods are Java™ methods that start in a language other than Java. Native methods can access system-specific functions and APIs that are not available directly in Java. The use of native methods limits the portability of an application, because it involves system-specific code.

Can we override native method?

The native methods can be overridden just like any other methods, unless they are declared final .


2 Answers

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.

like image 97
Olivier Samyn Avatar answered Oct 07 '22 16:10

Olivier Samyn


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.

like image 22
Winston Ewert Avatar answered Oct 07 '22 17:10

Winston Ewert