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.