What Is the Native Keyword in Java For

What is the native keyword in Java for?

The native keyword is applied to a method to indicate that the method is implemented in native code using JNI (Java Native Interface).

What are native methods in Java and where should they be used?

What are native methods in Java and where should they be used?

Once you see a small example, it becomes clear:

Main.java:

public class Main {
public native int intMethod(int i);
public static void main(String[] args) {
System.loadLibrary("Main");
System.out.println(new Main().intMethod(2));
}
}

Main.c:

#include <jni.h>
#include "Main.h"

JNIEXPORT jint JNICALL Java_Main_intMethod(
JNIEnv *env, jobject obj, jint i) {
return i * i;
}

Compile and run:

javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main

Output:

4

Tested on Ubuntu 14.04 with Oracle JDK 1.8.0_45.

So it is clear that it allows you to:

  • call a compiled dynamically loaded library (here written in C) with arbitrary assembly code from Java
  • and get results back into Java

This could be used to:

  • write faster code on a critical section with better CPU assembly instructions (not CPU portable)
  • make direct system calls (not OS portable)

with the tradeoff of lower portability.

It is also possible for you to call Java from C, but you must first create a JVM in C: How to call Java functions from C++?

Example on GitHub for you to play with.

Usage of native in Java

In my experience, the downsides of using native code libraries are significant:

  • JNI / JNA have a tendency to destabilize the JVM, especially if you try to do something complicated. If your native code gets native code memory management wrong, there's a chance that you will crash the JVM. If your native code is non-reentrant and gets called from more than one Java thread, bad things will happen ... sporadically. And so on.

  • Java with native code is harder to debug than pure Java or pure C/C++.

  • Native code can introduce significant platform dependencies / issues for an otherwise platform independent Java app.

  • Native code requires a separate build framework, and that may have platform / portability issues as well.

Generally speaking, you don't gain much (if any) extra performance by using native code. While you might think your C/C++ will be more performant than Java, the JIT compiler does a pretty good job of optimizing these days, and you have to consider the performance costs of making JNI calls and other interactions across the JNI boundary.

Generally specking, you should treat JNI / JNA as a "last resort" option. If there is any other way of solving the problem, that way is probably better.

Difference between using native keyword in

Using the native keyword indicates that the method is implemented in native code. (C / C++) using JNI. Since you also tagged android, here is some documentation for further clarification. JNI Tips - Android

What is a native implementation in Java?

These methods are either Intrinsic or written outside Java in "native" code, that is, specific to the given machine.

The ones you mention are Intrinsic and part of the JDK but you can also write native methods yourself using the Java Native Interface (JNI). This would normally use C to write the methods, but a lot of other languages, such as python allow you to write methods this way fairly easily. Code is written this way either for performance, or because it needs to access platform specific infrastructure which cannot be done in plain java.

In the case of hashcode(), this is implemented by the JVM. This is because often the hashcode will be related to something only the JVM knows. On early JVMs this was related to the object's location in memory - on other JVMs the Object may move in memory, and so a more complicated (but still very fast) scheme may be used.

what is difference between Java Method And Native Method?

A Java method is generically a code block with a name that you can write using plain java.

public void method() {
System.out.println("I'm a java method!");
}

A native method is a method that is linked to a native library. Native libraries are linked to a java program through JNI (Java Native Interface) or JNA (Java Native Access) and a native method looks like this:

public native void method();

It's just a declaration, because the method implementation is done in the native library.

Difference between native keyword and @HotSpotIntrinsicCandidate annotation

The javadoc comments for the @HotSpotIntrinsicCandidate annotation say the following:

"The @HotSpotIntrinsicCandidate annotation is specific to the HotSpot Virtual Machine. It indicates that an annotated method may be (but is not guaranteed to be) intrinsified by the HotSpot VM. A method is intrinsified if the HotSpot VM replaces the annotated method with hand-written assembly and/or hand-written compiler IR -- a compiler intrinsic -- to improve performance. The @HotSpotIntrinsicCandidate annotation is internal to the Java libraries and is therefore not supposed to have any relevance for application code."

In short, a method with this annotation1 may be specially optimized, but it depends on whether the HotSpot JVM knows how to optimize it. The implication is that:

  1. If the HotSpot JVM knows how to intrisify it, the Java method body is ignored.
  2. If the HotSpot JVM doesn't knows how to intrisify, the Java method body will be used in the normal way.
  3. Implementing the JVM code to do the intrinsification is non-trivial.
  4. You cannot make use of this in your own code. (It involves modify the core HotSpot JVM codebase.)

By contrast, declaring a method as native tells the JVM it must use a native code implementation. (The native method doesn't have a body.) The method's native code implementation may be provided by the JVM, or it may be provided by a dynamically loaded native library or DLL.) The call will typically1 be made via JNI / JNA and its calling sequence will be less performant than a conventional Java method call, and certainly an intrisified method call.

1 - In fact, the annotation is called @IntrinsicCandidate in Java 17.

2 - Some native methods in core Java SE classes (e.g. Object methods) are also marked as intrinsic. These may get optimized calling sequences.


So to answer your questions:

Which is more performative?

Intrisified method calls will be more performant.

Why use one over another and vice-versa?

  1. You (a regular Java programmer) can't usefully label methods in your apps as intrinsic. Regular and native methods your only options.

  2. The JVM implementors have a choice, but given the extra work involved, they tend to only make a method intrinsic when it will give a significant performance benefit. For example, it makes little sense to intrinsify the native method calls in java.io.* classes because the JNI method call overheads will be tiny compared with the other things that go on in a typical I/O operation.



Related Topics



Leave a reply



Submit