Native methods
What is it?
A native method is a Java method whose implementation is written in another programming language such as C or C++. The need to implement such a method comes from the fact that java is slower than a compiled language (even with the use of just-in-time compilers).
Don't forget to see the performance page if you want to know more on speed and memory issues.
Today, there are some standards used to create native methods:
An example
This example will explain step-by-step the creation of an application use C native code. This example uses Sun's JNI 1.1. It will also demonstrate C if faster than Java by doing 500 000 calls to strlen and to java.lang.String.length().
If you want to download all the files:
Create the Main.java file and compile it using javac Main.java
class Main
{
public static void main(String [] args)
{
CJava j=new CJava();
System.out.println(j.perfTest("Just a Test!"));
}
}
Create the CJava.java file and compile it using javac CJava.java
class CJava
static {
System.loadLibrary("CJava");
}
public int compute(String s) {
return s.length();
}
public native String perfTest(String s);
}
This class contains the definition for the perfTest method. It will be called by the main method to display a String. This class also loads the CJava.dll (Win32), or the CJava.so (Unix) dynamic library. Note that the mapping from a library name to a specific filename is done in a system-specific manner.
The compute() method is used to return the string length to the native code. It would be faster to call directly the java.lang.String.length() method from native code, but the example would become less clear.
Create the .h file using javah -jni CJava
This tool generate a header file with a .h extension contains the header for the perfTest C native method. You don't need to modify this file.
Create the CJava.cpp file and compile it.
#include
#include
#include
#include "CJava.h"
JNIEXPORT jstring JNICALL Java_CJava_perfTest(JNIEnv *env, jobject obj, jstring s)
{
char *buf=new char[100];
long a,i,j;
printf("Entering native method.\n\n");
const char *str=env->GetStringUTFChars(s,0);
printf("The input string is: %s\n",str);
jclass cls = env->GetObjectClass(obj);
jmethodID mid = env->GetMethodID(cls, "compute", "(Ljava/lang/String;)I");
printf("Using C function to get the string length:\n");
for (a=1;a<500000;a++) j=strlen(str);
printf("C size: %d\n",j);
printf("Calling java method from native code to get the string length:\n");
for (a=1;a<500000;a++) i=env->CallIntMethod(obj, mid,s);
printf("Java size: %d\n",i);
printf("Creating the string returned by the function.\n");
sprintf(buf,"\nString %s :\nJava length=%d\nC length=%d\n",str,i,j);
env->ReleaseStringUTFChars(s,0);
printf("Leaving native code.\n");
return env->NewStringUTF(buf);
}
To compile it on a win32 machine using Visual C++ 5.0, simply enter the command:
cl -I"C:\program files\javasoft\jdk1.1.4\include" -I"C:\program files\javasoft\jdk1.1.4\include\win32" /LD CJava.cpp
Launch the main class using java Main
You should see a big performance difference between the first loop (using strlen() C function) and the other one (using java.lang.String.length()). A large overhead for calling java methods inside native code make this example unuseful.
This page was last updated 06 March 1998